日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
微服務(wù)實(shí)現(xiàn)單點(diǎn)登錄(SSO)授權(quán)服務(wù)器

一、單點(diǎn)登錄SSO介紹

目前每家企業(yè)或者平臺都存在不止一套系統(tǒng),由于歷史原因每套系統(tǒng)采購于不同廠商,所以系統(tǒng)間都是相互獨(dú)立的,都有自己的用戶鑒權(quán)認(rèn)證體系,當(dāng)用戶進(jìn)行登錄系統(tǒng)時,不得不記住每套系統(tǒng)的用戶名密碼,同時,管理員也需要為同一個用戶設(shè)置多套系統(tǒng)登錄賬號,這對系統(tǒng)的使用者來說顯然是不方便的。我們期望的是如果存在多個系統(tǒng),只需要登錄一次就可以訪問多個系統(tǒng),只需要在其中一個系統(tǒng)執(zhí)行注銷登錄操作,則所有的系統(tǒng)都注銷登錄,無需重復(fù)操作,這就是單點(diǎn)登錄(Single Sign On 簡稱SSO)系統(tǒng)實(shí)現(xiàn)的功能。

單點(diǎn)登錄是系統(tǒng)功能的定義,而實(shí)現(xiàn)單點(diǎn)登錄功能,目前開源且流行的有CAS和OAuth2兩種方式,過去我們用的最多的是CAS,現(xiàn)在隨著SpringCloud的流行,更多人選擇使用SpringSecurity提供的OAuth2認(rèn)證授權(quán)服務(wù)器實(shí)現(xiàn)單點(diǎn)登錄功能。

OAuth2是一種授權(quán)協(xié)議的標(biāo)準(zhǔn),任何人都可以基于這個標(biāo)準(zhǔn)開發(fā)Oauth2授權(quán)服務(wù)器,現(xiàn)在百度開放平臺、騰訊開放平臺等大部分的開放平臺都是基于OAuth2協(xié)議實(shí)現(xiàn), OAuth2.0定義了四種授權(quán)類型,最新版OAuth2.1協(xié)議定義了七種授權(quán)類型,其中有兩種因安全問題已不再建議使用:

【OAuth2.1 建議使用的五種授權(quán)類型】

  • Authorization Code 【授權(quán)碼授權(quán)】:用戶通過授權(quán)服務(wù)器重定向URL返回到客戶端后,應(yīng)用程序從URL中獲取授權(quán)碼,并使用授權(quán)碼請求訪問令牌。
  • PKCE【Proof Key for Code Exchange 授權(quán)碼交換證明密鑰】:授權(quán)碼類型的擴(kuò)展,用于防止CSRF和授權(quán)碼注入攻擊。
  • Client Credentials【客戶端憑證授權(quán)】:直接由客戶端使用客戶端 ID 和客戶端密鑰向授權(quán)服務(wù)器請求訪問令牌,無需用戶授權(quán),通常用于系統(tǒng)和系統(tǒng)之間的授權(quán)。
  • Device Code【設(shè)備代碼授權(quán)】:用于無瀏覽器或輸入受限的設(shè)備,使用提前獲取好的設(shè)備代碼獲取訪問令牌。
  • Refresh Token【刷新令牌授權(quán)】:當(dāng)訪問令牌失效時,可以通過刷新令牌獲取訪問令牌,不需要用戶進(jìn)行交互。

【OAuth2.1 不建議/禁止使用的兩種授權(quán)類型】

  • Implicit Flow【隱式授權(quán)】:隱式授權(quán)是以前推薦用于本機(jī)應(yīng)用程序和 JavaScript 應(yīng)用程序的簡化 OAuth 流程,其中訪問令牌立即返回,無需額外的授權(quán)代碼交換步驟。其通過HTTP重定向直接返回訪問令牌,存在很大的風(fēng)險,不建議使用,有些授權(quán)服務(wù)器直接禁止使用此授權(quán)類型。
  • Password Grant【密碼授權(quán)】:客戶端通過用戶名密碼向授權(quán)服務(wù)器獲取訪問令牌。因客戶端需收集用戶名和密碼,所以不建議使用,最新的 OAuth 2 安全最佳實(shí)踐完全不允許密碼授權(quán)。

【SpringSecurity對OAuth2協(xié)議的支持】:

通過SpringSecurity官網(wǎng)可知,通過長期的對OAuth2的支持,以及對實(shí)際業(yè)務(wù)的情景考慮,大多數(shù)的系統(tǒng)都不需要授權(quán)服務(wù)器,所以,Spring官方不再推薦使用spring-security-oauth2,SpringSecurity逐漸將spring-security-oauth2中的OAuth2登錄、客戶端、資源服務(wù)器等功能抽取出來,集成在SpringSecurity中,并單獨(dú)新建spring-authorization-server項(xiàng)目實(shí)現(xiàn)授權(quán)服務(wù)器功能。

目前我們了解最多的是Spring Security OAuth對OAuth2協(xié)議的實(shí)現(xiàn)和支持,這里需要區(qū)分Spring Security OAuth和Spring Security是兩個項(xiàng)目,過去OAth2相關(guān)功能都在Spring Security OAuth項(xiàng)目中實(shí)現(xiàn),但是自SpringSecurity5.X開始,SpringSecurity項(xiàng)目開始逐漸增加Spring Security OAuth中的功能,自SpringSecurity5.2開始,添加了OAuth 2.0 登錄, 客戶端, 資源服務(wù)器的功能。但授權(quán)服務(wù)器的功能,并不打算集成在SpringSecurity項(xiàng)目中,而是新建了spring-authorization-server項(xiàng)目作為單獨(dú)的授權(quán)服務(wù)器:詳細(xì)介紹。spring-security實(shí)現(xiàn)的是OAuth2.1協(xié)議,spring-security-oauth2實(shí)現(xiàn)的是OAuth2.0協(xié)議。

Spring未來的計劃是將 Spring Security OAuth 中當(dāng)前的所有功能構(gòu)建到 Spring Security 5.x 中。 在 Spring Security 達(dá)到與 Spring Security OAuth 的功能對等之后,他們將繼續(xù)支持錯誤和安全修復(fù)至少一年。

【GitEgg框架單點(diǎn)登錄實(shí)現(xiàn)計劃】:

因spring-authorization-server目前最新發(fā)布版本0.2.3,部分功能仍在不斷地修復(fù)和完善,還不足以應(yīng)用到實(shí)際生產(chǎn)環(huán)境中,所以,我們目前使用spring-security-oauth2作為授權(quán)服務(wù)器,待后續(xù)spring-authorization-server發(fā)布穩(wěn)定版本后,再進(jìn)行遷移升級。

【spring-security-oauth2默認(rèn)實(shí)現(xiàn)的授權(quán)類型】:

  • 隱式授權(quán)(Implicit Flow)【spring-authorization-server不再支持此類型】。
  • 授權(quán)碼授權(quán)(Authorization Code)。
  • 密碼授權(quán)(Password Grant)【spring-authorization-server不再支持此類型】。
  • 客戶端憑證授權(quán)(Client Credentials)。
  • 刷新令牌授權(quán) (Refresh Token)。

在GitEgg微服務(wù)框架中,gitegg-oauth已經(jīng)引入了spring-security-oauth2,代碼中使用了了Oauth2的密碼授權(quán)和刷新令牌授權(quán),并且自定義擴(kuò)展了【短信驗(yàn)證碼授權(quán)類型】和【圖形驗(yàn)證碼授權(quán)】,這其實(shí)是密碼授權(quán)的擴(kuò)展授權(quán)類型。

目前,基本上所有的SpringCloud微服務(wù)授權(quán)方式都是使用的OAuth2密碼授權(quán)模式獲取token,可能你會有疑惑,為什么上面最新的Oauth2協(xié)議已經(jīng)不建議甚至是禁止使用密碼授權(quán)類型了,而我們GitEgg框架的系統(tǒng)管理界面還要使用密碼授權(quán)模式來獲取token?因?yàn)椴唤ㄗh使用密碼授權(quán)類型的原因是第三方客戶端會收集用戶名密碼,存在安全風(fēng)險。而在我們這里,我們的客戶端是自有系統(tǒng)管理界面,不是第三方客戶端,所有的用戶名密碼都是我們自有系統(tǒng)的用戶名密碼,只要做好系統(tǒng)安全防護(hù),就可最大限度的避免用戶名密碼泄露給第三方的風(fēng)險。

在使用spring-security-oauth2實(shí)現(xiàn)單點(diǎn)登錄之前,首先我們一定要搞清楚單點(diǎn)登錄SSO、OAuth2、spring-security-oauth2的區(qū)別和聯(lián)系:

  • 單點(diǎn)登錄SSO是一種系統(tǒng)登錄解決方案的定義,企業(yè)內(nèi)部系統(tǒng)登錄以及互聯(lián)網(wǎng)上第三方QQ、微信、GitHub登錄等都是單點(diǎn)登錄。
  • OAuth2是一種系統(tǒng)授權(quán)協(xié)議,它包含多種授權(quán)類型,我們可以使用授權(quán)碼授權(quán)和刷新令牌授權(quán)兩種授權(quán)類型來實(shí)現(xiàn)單點(diǎn)登錄功能。
  • spring-security-oauth2是對OAuth2協(xié)議中授權(quán)類型的具體實(shí)現(xiàn),也是我們實(shí)現(xiàn)單點(diǎn)登錄功能實(shí)際用到的代碼。

二、SpringSecurity單點(diǎn)登錄服務(wù)端和客戶端實(shí)現(xiàn)流程解析

單點(diǎn)登錄業(yè)務(wù)流程時序圖:

A系統(tǒng)(單點(diǎn)登錄客戶端)首次訪問受保護(hù)的資源觸發(fā)單點(diǎn)登錄流程說明

1、用戶通過瀏覽器訪問A系統(tǒng)被保護(hù)的資源鏈接。

2、A系統(tǒng)判斷當(dāng)前會話是否登錄,如果沒有登錄則跳轉(zhuǎn)到A系統(tǒng)登錄地址/login。

3、A系統(tǒng)首次接收到/login請求時沒有state和code參數(shù),此時A系統(tǒng)拼接系統(tǒng)配置的單點(diǎn)登錄服務(wù)器授權(quán)url,并重定向至授權(quán)鏈接。

4、單點(diǎn)登錄服務(wù)器判斷此會話是否登錄,如果沒有登錄,那么返回單點(diǎn)登錄服務(wù)器的登錄頁面。

5、用戶在登錄頁面填寫用戶名、密碼等信息執(zhí)行登錄操作。

6、單點(diǎn)登錄服務(wù)器校驗(yàn)用戶名、密碼并將登錄信息設(shè)置到上下文會話中。

7、單點(diǎn)登錄服務(wù)器重定向到A系統(tǒng)的/login鏈接,此時鏈接帶有code和state參數(shù)。

8、A系統(tǒng)再次接收到/login請求,此請求攜帶state和code參數(shù),系統(tǒng)A通過OAuth2RestTemplate請求單點(diǎn)登錄服務(wù)端/oauth/token接口獲取token。

9、A系統(tǒng)獲取到token后,首先會對token進(jìn)行解析,并使用配置的公鑰對token進(jìn)行校驗(yàn)(非對稱加密),如果校驗(yàn)通過,則將token設(shè)置到上下文,下次訪問請求時直接從上下文中獲取。

10、A系統(tǒng)處理完上下問會話之后重定向到登錄前請求的受保護(hù)資源鏈接。

B系統(tǒng)(單點(diǎn)登錄客戶端)訪問受保護(hù)的資源流程說明

1、用戶通過瀏覽器訪問B系統(tǒng)被保護(hù)的資源鏈接。

2、B系統(tǒng)判斷當(dāng)前會話是否登錄,如果沒有登錄則跳轉(zhuǎn)到B系統(tǒng)登錄地址/login。

3、B系統(tǒng)首次接收到/login請求時沒有state和code參數(shù),此時B系統(tǒng)拼接系統(tǒng)配置的單點(diǎn)登錄服務(wù)器授權(quán)url,并重定向至授權(quán)鏈接。

4、單點(diǎn)登錄服務(wù)器判斷此會話是否登錄,因上面訪問A系統(tǒng)時登陸過,所以此時不會再返回登錄界面。

5、單點(diǎn)登錄服務(wù)器重定向到B系統(tǒng)的/login鏈接,此時鏈接帶有code和state參數(shù)。

6、B系統(tǒng)再次接收到/login請求,此請求攜帶state和code參數(shù),系統(tǒng)B通過OAuth2RestTemplate請求單點(diǎn)登錄服務(wù)端/oauth/token接口獲取token。

7、B系統(tǒng)獲取到token后,首先會對token進(jìn)行解析,并使用配置的公鑰對token進(jìn)行校驗(yàn)(非對稱加密),如果校驗(yàn)通過,則將token設(shè)置到上下文,下次訪問請求時直接從上下文中獲取。

8、B系統(tǒng)處理完上下問會話之后重定向到登錄前請求的受保護(hù)資源鏈接。

spring-security-oauth2 單點(diǎn)登錄代碼實(shí)現(xiàn)流程說明:

1、用戶通過瀏覽器訪問單點(diǎn)登錄被保護(hù)的資源鏈接。

2、SpringSecurity通過上下文判斷是否登錄(SpringSecurity單點(diǎn)登錄服務(wù)端和客戶端默認(rèn)都是基于session的),如果沒有登錄則跳轉(zhuǎn)到單點(diǎn)登錄客戶端地址/login。

3、單點(diǎn)登錄客戶端OAuth2ClientAuthenticationProcessingFilter攔截器通過上下文獲取token,因第一次訪問單點(diǎn)登錄客戶端/login時,沒有code和state參數(shù),所以拋出UserRedirectRequiredException異常。

4、單點(diǎn)登錄客戶端捕獲UserRedirectRequiredException異常,并根據(jù)配置文件中的配置,組裝并跳轉(zhuǎn)到單點(diǎn)登錄服務(wù)端的授權(quán)鏈接/oauth/authorize,鏈接及請求中會帶相關(guān)配置參數(shù)。

5、單點(diǎn)登錄服務(wù)端收到授權(quán)請求,根據(jù)session判斷是否此會話是否登錄,如果沒有登錄則跳轉(zhuǎn)到單點(diǎn)登錄服務(wù)器的統(tǒng)一登錄界面(單點(diǎn)登錄服務(wù)端也是根據(jù)session判斷是否登錄的,在這里為了解決微服務(wù)的session集群共享問題,引入了spring-session-data-redis)。

6、用戶完成登錄操作后,單點(diǎn)登錄服務(wù)端重定向到單點(diǎn)登錄客戶端的/login鏈接,此時鏈接帶有code和state參數(shù)。

7、再次用到第三步的OAuth2ClientAuthenticationProcessingFilter攔截器通過上下文獲取token,此時上下文中肯定沒有token,所以會通過OAuth2RestTemplate請求單點(diǎn)登錄服務(wù)端/oauth/token接口使用重定向獲得的code和state換取token。

8、單點(diǎn)登錄客戶端獲取到token后,首先會對token進(jìn)行解析,并使用配置的公鑰對token進(jìn)行校驗(yàn)(非對稱加密),如果校驗(yàn)通過,則將token設(shè)置到上下文,下次訪問請求時直接從上下文中獲取。

9、單點(diǎn)登錄客戶端處理完上下問會話之后重定向到登錄前請求的受保護(hù)資源鏈接。

三、使用【授權(quán)碼授權(quán)】和【刷新令牌授權(quán)】來實(shí)現(xiàn)單點(diǎn)登錄服務(wù)器

1、自定義單點(diǎn)登錄服務(wù)器頁面

當(dāng)我們的gitegg-oauth作為授權(quán)服務(wù)器使用時,我們希望定制自己的登錄頁等信息,下面我們自定義登錄、主頁、錯誤提示頁、找回密碼頁。其他需要的頁面可以自己定義,比如授權(quán)確認(rèn)頁,我們此處業(yè)務(wù)不需要用戶二次確認(rèn),所以這里沒有自定義此頁面。

在gitegg-oauth工程的pom.xml中添加Thymeleaf依賴,作為Spring官方推薦的模板引擎,我們使用Thymeleaf來實(shí)現(xiàn)前端頁面的渲染展示。

 

org.springframework.boot
spring-boot-starter-thymeleaf

在GitEggOAuthController中新增頁面跳轉(zhuǎn)路徑:

 /**
* 單點(diǎn)登錄-登錄頁
* @return
*/
@GetMapping("/login") public String login() {
return "login";
}

/**
* 單點(diǎn)登錄-首頁:當(dāng)直接訪問單點(diǎn)登錄系統(tǒng)成功后進(jìn)入的頁面。從客戶端系統(tǒng)進(jìn)入的,直接返回到客戶端頁面
* @return
*/
@GetMapping("/index") public String index() {
return "index";
}

/**
* 單點(diǎn)登錄-錯誤頁
* @return
*/
@GetMapping("/error") public String error() {
return "error";
}

/**
* 單點(diǎn)登錄-找回密碼頁
* @return
*/
@GetMapping("/find/pwd") public String findPwd() {
return "findpwd";
}

在resources目錄下新建static(靜態(tài)資源)目錄和templates(頁面代碼)目錄,新增favicon.ico文件。

自定義登錄頁login.html代碼:








統(tǒng)一身份認(rèn)證平臺

























自定義登錄login.js代碼:

var countdown=60;
jQuery(function ($) {
countdown = 60;
$('.account-form').bootstrapValidator({
message: '輸入錯誤',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
username: {
container: '.input-account-wrapper',
message: '輸入錯誤',
validators: {
notEmpty: {
message: '用戶賬號不能為空'
},
stringLength: {
min: 2,
max: 32,
message: '賬號長度范圍2-32個字符。'
},
regexp: {
regexp: /^[a-zA-Z0-9_\.]+$/,
message: '用戶名只能由字母、數(shù)字、點(diǎn)和下劃線組成'
}
}
},
password: {
container: '.input-psw-wrapper',
validators: {
notEmpty: {
message: '密碼不能為空'
},
stringLength: {
min: 5,
max: 32,
message: '密碼長度范圍6-32個字符。'
}
}
}
}
});
$('.mobile-form').bootstrapValidator({
message: '輸入錯誤',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
phone: {
message: '輸入錯誤',
container: '.input-phone-wrapper',
validators: {
notEmpty: {
message: '手機(jī)號不能為空'
},
regexp: {
regexp: /^1\d{10}$/,
message: '手機(jī)號格式錯誤'
}
}
},
code: {
container: '.input-sms-wrapper',
validators: {
notEmpty: {
message: '驗(yàn)證碼不能為空'
},
stringLength: {
min: 6,
max: 6,
message: '驗(yàn)證碼長度為6位。'
}
}
}
}
});

var options={
beforeSerialize: beforeFormSerialize,
success: formSuccess,//提交成功后執(zhí)行的回掉函數(shù)
error: formError,//提交失敗后執(zhí)行的回掉函數(shù)
headers : {"TenantId" : 0},
clearForm: true,//提交成功后是否清空表單中的字段值
restForm: true,//提交成功后是否充值表單中的字段值,即恢復(fù)到頁面加載是的狀態(tài)
timeout: 6000//設(shè)置請求時間,超過時間后,自動退出請求,單位(毫秒)
}
var mobileOptions={
名稱欄目:微服務(wù)實(shí)現(xiàn)單點(diǎn)登錄(SSO)授權(quán)服務(wù)器
網(wǎng)站網(wǎng)址:http://www.dlmjj.cn/article/dhcpsdp.html