




下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第9章用戶認上面流程圖描述了用戶要操作的各個微服務,用戶查看個人信息需要客戶微服務,下單需要訂單微服務,秒殺搶購商品需要秒殺微服務。每個服務都需要認證用戶的,認證成功后,需要識別用戶的角色然后對應的功能。單點登用戶的項目中,至少有3個微服務需要識別用戶,如果用戶每個微服務都登錄一次就太麻煩了,為了提高用戶的體驗,我們需要實現(xiàn)讓用戶在一個系統(tǒng)中登錄,其他任意受信任的系統(tǒng)都可以訪問,這個功能就叫單點登錄。單點登錄(SingleSignOn),簡稱為SSO,是目前比較流行的企業(yè)業(yè)務整合的解決方案之一。SSO的第賬號登隨著國內及國外巨頭們的平臺開放以及移動互聯(lián)網(wǎng)的發(fā)展,第登錄已經(jīng)不是一個陌生的產(chǎn)品設計概念了。所謂的第登錄,是說基于用戶在第平臺上已有的賬號和來快速完成己方應用的 等,國內的比如、、QQ等222.1單點登錄技術方Java中有很多用戶認證的框架都可以實現(xiàn)單點2.22.2登錄技術方1、ApacheShiro.3、SpringOauth2認證第認證技術方案最主要是解決認證協(xié)議的通用標準問題,因為要實現(xiàn)跨系統(tǒng)認證,各系統(tǒng)之間要遵循一定的接口協(xié)議。AUH協(xié)議為用戶資源的提供了一個安全的、開放而又簡易的標準。同時任何第都可以使用AUH認證服務,任何服務提供商都可以實現(xiàn)自身的AUH認證服務,因而AUH是開放的。業(yè)界提供了AUH的多種實現(xiàn)如PP、JvScip,Java,Ruy等各種語言開發(fā)包,大大節(jié)約了程序員的時間,因而OAUTH是簡易的?;ヂ?lián)網(wǎng)很多服務如OpenAPI,很多大公司如 資源的標準。Oauth協(xié)議目前發(fā)展到2.0版本,1.0版本過于復雜,2.0版本已得到廣泛應用。參 ?fr=aladdinOauth協(xié)議:ml/rfc6749下邊分析一個Oauth2認證的例子,程序員使用 ,開始 會對資源擁有者的進行驗證,驗證權,QQ認證服務器會頒發(fā)一個碼,并重定向到程序員的3.3.客戶端獲取到 碼,請求認證服務器申請令牌此過程用戶看不到,客戶端應用程序請求認證服務 員看到已經(jīng)登錄成功客戶端請求資源服務器的資源客戶端攜帶令牌資源服務器的資源。程序員攜帶令牌請求服務器獲取用戶的基本信息。資源服務器返回受保護資源資源服務器校驗令牌的,如果合法則向用戶響應資源信息內容。注意:資源服務器和認證服務器可以是一個服務也可以分開的服務,如果是分開的服務資源服務器通常要請求認證服務器來校驗令牌的。Oauth2.0認證流程如下:引自Oauth2.0協(xié)議rfc67491、客戶端本身不資源,需要通過資源擁有者的去請求資源服務器的資源,比如:暢 2、資源擁有者通常為用戶,也可以是應用程序,即該資源的3、服務器(也稱認證服務器)用來對資源擁有的進行認證、對資源進行??蛻舳艘胭Y源需要通過認證服務器由資源擁有者授權后方可。4、資源服務器資源的服務器,比如,暢購用戶管理服務器了暢購的用戶信息, Oauth2在項目的應Oauth2可以實現(xiàn)實現(xiàn)如下功能1、本系統(tǒng)第系統(tǒng)的資3、本系統(tǒng)前端(客戶端)本系統(tǒng)后端微服務的資源4、本系統(tǒng)微服務之間資源,例如:微服務A微服務B的資源,BA的資源2.3SpringsecurityOauth2認證解決本項目采用Srigscrity+JW完成用戶認證及用戶,Srigscrity是一個強大的和高度可定制的驗證和控制框架,Srigscrity框架集成了Oath協(xié)議,下圖是項目認證架構圖:2、認證服務下發(fā)用戶令牌,擁有令牌表示合法4、網(wǎng)關校驗用戶令牌的合法,不合法表示用戶沒有登錄,如果合法則放行繼續(xù)6、資源服務完成則響應資源信息Jwt令牌JSONWebToken(JWT)是一個開放的行業(yè)標準(RFC7519),它定義了一種簡介的、自包含的協(xié)議格式,用于在通信雙方傳遞json對象,傳遞的信息經(jīng)過數(shù)字簽名可以被驗證和信任。JWT可以使用 HMAC算法或使用RSA的公鑰/私鑰對來簽名,防止被篡改。4、資源服務使用JWT可不依賴認證服務即可完 2、以2、以在令牌自定義富的內容,易展。{{"sub":""name":"admin":}3.1令牌結頭部包括令牌的類型(即JWT)及使用的哈希算法(如HMACSHA256或RSA)第二部分是負載,內容也是一個jso對象,它是存放有效信息的地方,它可以存放jw如:s(簽發(fā)者)xp(過期時間戳),su(面向的用戶)等,也可自定義字段。此部分不建議存放敏感信息,因為此部分可 {"alg":"typ":}1、JWT令牌較長, 空間比較大簽名算法進行簽名。一個例子base6UrlEncode(header)+.base64UrlEncode(header):jwt令牌的第一部分。base64UrlEncode(payload):jwt令牌的第二部分。base6UrlEncode(header)+.生成私鑰公1、生成密鑰下邊命令生成密鑰,采用RSA算法每個包含公鑰和私KeytoolKeytool是一個java提供 查 keytool-list-keystore-alias:密鑰的別-keyalg:使用的hash算-keypass:密鑰-keystore:密鑰庫文件名,changgou.jks保存了生-storepass:密鑰庫keytool-genkeypair-aliaschanggou-keyalgRSA-keypasschanggou-keystorechanggou.jks-storepasschanggou2、導出公安 執(zhí)行如下命令keytoolkeytool-list-rfc--keystorechanggou.jks|opensslx509-informpem- -----BEGINPUBLICKEY---- -----ENDPUBLICKEY----基于私鑰生成jwt令將課件中changgou_user_auth的工程導入到項目中去,如下publicpublicclassCreateJwtTest*創(chuàng)建令牌測試publicvoid 文件路String//String//秘Stringkeypwd=//秘鑰別Stringalias=路ClassPathResourceresource=new//創(chuàng)建秘鑰工KeyStoreKeyFactorykeyStoreKeyFactory=new KeyPairkeyPair=//獲取私RSAPrivateKeyrsaPrivate=(RSAPrivateKey)//定義Map<String,Object>tokenMap=newHashMap<>();tokenMap.put("id","1");tokenMap.put("name","itheima");tokenMap.put("roles","ROLE_VIP,ROLE_USER");//生成Jwt令//取出令Stringencoded=jwt.getEncoded();}}基于公鑰解析jwt令在chan 創(chuàng)建測試類 .chaggo.toePsJwtst實現(xiàn)解析校驗令牌據(jù),代碼如下:publicpublicclassParseJwtTest*校驗令牌publicvoid//令Stringtoken=//公Stringpublickey="-----BEGINPUBLICKEY----- PUBLIC //校驗Jwtjwt=JwtHelper.decodeAndVerify(token,new//獲取Jwt原始內Stringclaims=jwt.getClaims();//jwt令Stringencoded=jwt.getEncoded();}}Oauth2.04.1準備工1)搭建認證服務器之前,先在用戶系統(tǒng)表結構中增加如下表結`resource_ids``resource_ids`varchar(256)DEFAULT`client_secret`varchar(256)DEFAULTNULLCOMMENT'客戶端秘鑰,`scope`varchar(256)DEFAULTNULLCOMMENT'對應的范圍`authorized_grant_types`varchar(256)DEFAULTNULLCOMMENT'認證模式`web_server_redirect_uri`varchar(256)DEFAULTNULLCOMMENT'認證后重定向地址`authorities`varchar(256)DEFAULT`access_token_validity`int(11)DEFAULTNULLCOMMENT'令牌有效期`refresh_token_validity`int(11)DEFAULTNULLCOMMENT'令牌刷新周期`additional_information`varchar(4096)DEFAULT`autoapprove`varchar(256)DEFAULTNULL,PRIMARYKEY(`client_id`))ENGINE=InnoDBDEFAULT4.24.2 模式介Oauth2有以 碼模式(Authorization隱 模式模式(ResourceOwnerPassword客戶端模式(ClientINSERTINTO`oauth_client_details`VALUES('changgou',null,'$2a$10$Yvkp3xzDcri6MAsPIqnzzeGBHez1QZR3A079XDdmNU4R725KrkXi2','app', ',null,'43200','43200',null,其中碼模式和模式應用較多,本小節(jié)介紹碼模式4.2.1碼模碼流1、客戶端請求3、客戶端獲取到碼,請求認證服務器申請令5、客戶端請求資源服務器的資源,資源服務校驗令牌,完請請求認證服務獲 client_id:客戶端id, 配置類中設置的客戶端id一致 redirect_uri:跳轉uri, 碼申請成功后會跳轉到此地址,并在后邊帶上code參數(shù) 碼Get?首先跳轉到登錄頁面輸入賬號和 ,點擊i。SrigSecuiy接收到請求會調用UsrDtlsService接口的lUsrByUsra方法查詢用戶正確的。當前導入的基礎工程中客戶端D為cag也為cag即可認證通過。點擊點擊Atoriz,接下來返回 碼:認證服務攜帶 碼跳轉eiect_ur,code=k45iY就是回的授權碼,每一個 碼只能使用一次申請拿到碼后,申請令牌Post請求 類型,填寫authorization_code,表 碼模 碼,就是剛剛獲取 碼,注意 碼只使用一次就無效了,需要重新申請redirect_uri:申 碼時的跳轉url,一定和申 碼時用的redirect_uri一致此需要使用httpBasic認證。什么是httpBasic認證?base64編碼,放在header中請求服務端,一個例子:Athorization:BsicWZWJBcA6NZWJBcA=NZWJBcA6ZWJBcA=名:的bse64編碼。認證失敗服務端返回401Unauthorized。httpbasic認證客戶端Id和客戶 會匹客戶端Id和客戶 會匹配數(shù)據(jù)庫oauth_client_details表中的客戶端id及客戶 返返回信如下用用BearerToken(http:/ token_type:有MACtoken_type:有MACokenBeareroken種類型,種的校驗算法同,RC6750建議Oauth2SpringSecurityOauth2提供校驗令牌的Get:token?token=參數(shù)token使用postman測試如下如果令牌校驗失敗,會出現(xiàn)刷新 固定 refresh_token:刷新令牌(注意不是access_token,而是4.2.2模模式(ResourceOwnerPasswordCredentials)與碼模式的區(qū)別是申請令牌不再使用碼,而是直接通過用戶名和即可申請令牌。申請令牌PostPost請求攜帶參數(shù) 并且此需要使用httpBasic認證測試數(shù)據(jù)如下4.3資源服資源服務擁有要的受保護資源,客戶端攜帶令牌資源服務,如果令牌合法則可成功資源服務中的資源,如下圖:上圖上圖的業(yè)務流程如下4.3.1用戶服務對接1、客戶端請求認證服務申請令2、認證服務生成令牌認證服務采用非對稱加密算法,使用私鑰生成令 資源服務客戶端在Httpheader中添加:Authorization:Bearer令牌。 5、令牌有效,資源服務向客戶端響應資源信基本上所有微服務都是資源服務,這里我們在課程管理服務上配置控制,當配置了控制后如課程信息則必須提供令牌。2、添加依 @EnableGlobalMethodSecurity(prePostEnabled=true,securedEnabled=true)//激活方publicclassResourceServerConfigextendsResourceServerConfigurerAdapter//公privatestaticfinalStringPUBLIC_KEY=定義@parampublicTokenStoretokenStore(JwtAccessTokenConverterjwtAccessTokenConverter){returnnew}定義publicJwtAccessTokenConverterreturn}獲取非對稱加密公鑰<artifactId>spring-cloud-starter-privateprivateStringgetPubKey()Resourceresource=newClassPathResource(PUBLIC_KEY);try{InputStreamReaderinputStreamReader=newreturnbr.lines().collect(Collectors.joining("\n"));}catch(IOException{return}}Http安全配置,對每個到達系統(tǒng)的http請 進行校@param@throwspublicvoidconfigure(HttpSecurityhttp)throwsException//"/user/add").// 址放 //}}4.3.2資源服務測不攜帶令由于該地址受限制,需要,所以出現(xiàn)如下錯誤{{"error":"error_description":"Fullauthenticationisrequiredtoaccessthis}攜帶在httpheader中添加Authorization:Bearer11、用戶登錄,請求認證服2、認證服務認證通過,生成jwt令牌,將jwt令牌及相關信息寫入Redis,并且 令牌寫3、用 資源頁面,帶 到網(wǎng)4、網(wǎng)關 獲取token,并查詢Redis校驗token,如果token不存在 ,否則放5、用戶退出,請求認證服務,清除redis中的token,并且刪 中的當輸入錯誤的令牌也無法正當輸入錯誤的令牌也無法正 需求分功能流程圖如下執(zhí)行流執(zhí)行流程使用 用客戶客戶 2、由jwt令牌過2、由jwt令牌過長,宜,所以將jwt在在redis,由客戶端請求服務端獲取并在將認證服務changgou_user_auth中的aplicatio.yl配置文件中的Rs配置改成自己對應的端口和密碼。認證服認證服務需要實現(xiàn)的功能如1、登錄接 將令牌寫。2、退出接口校驗當前用戶的為合法并且為已登錄狀態(tài)。將令牌從redis刪除。刪除 ttl:1200#token clientId:changgou clientSecret:changgou#客戶端秘鑰: 保存對應MaxAge:- 過期時間,-1表示瀏覽器關閉則銷為了不破壞SrigSecuiy的代碼,我們在Svic方法中通過estemlat請求SrigSecrty露的申請令牌接口來申請令牌,下邊是測試代碼:publicprivateLoadBalancerClientprivateRestTemplate*發(fā)送Http請求創(chuàng)建令publicvoidtestCreateToken()throwsInterruptedException//采用客戶端負載均衡,從eureka獲取認證服務的ip和端ServiceInstanceserviceInstance=
URIuri=//申請令牌地StringauthUrl=uri+//1、header信息,包括了httpbasic認證信MultiValueMap<String,String>headers=newLinkedMultiValueMap<String,//進行Base64編碼,并將編碼后的認證數(shù)據(jù)放到頭Stringhttpbasic=httpbasic("changgou","changgou");headers.add("Authorization",httpbasic);//2、指定認證MultiValueMap<String,String>body=newLinkedMultiValueMap<String,HttpEntity<MultiValueMap<String,String>>(body,headers);//指 restTemplate當遇到400或401響應時候也不要拋出異常,也要正常返回restTemplate.setErrorHandler(new{IOException{//當響應的值為400或401時候也要正常響應,不要拋出if(response.getRawStatusCode()!=400&&response.getRawStatusCode()!=401){}} 調用申請令ResponseEntity<Map>exchange=restTemplate.exchange(authUrl,HttpMethod.POST,multiValueMapHttpEntity,Map.class);Mapresult=exchange.getBody();}@param@paramprivateStringhttpbasic(StringclientId,String//將客戶端id和客戶 拼接,按“客戶端id:客戶 Stringstring=//進行base64byte[]encode=Base64Utils.encode(string.getBytes());return"Basic"+newString(encode);}}AuthServiceImplAuthServiceImpl實現(xiàn)publicclassAuthServiceImplimplementsAuthServiceprivateRestTemplateprivateLoadBalancerClientprivateStringRedisTemplateprivatelongttl;申請@param@param@param@parampublicAuthTokenapplyToken(Stringusername,Stringpassword,StringclientId,StringclientSecret){publicinterfaceAuthServiceAuthTokenlogin(Stringusername,Stringpassword,StringclientId,String}URIuri=serviceInstance.getUri();Stringurl=uri+"/oauth/token";MultiValueMap<String,String>body=newLinkedMultiValueMap<>();MultiValueMap<String,String>headers=newLinkedMultiValueMap<>();DefaultResponseErrorHandler(){@OverrideIOException{if(response.getRawStatusCode()!=400&&}}ResponseEntity<Map>responseEntity=restTemplate.exchange(url,HttpMethod.POST,requestEntity,Map.class);Mapmap=if(map==null||map.get("access_token")==null||map.get("refresh_token")==null||thrownewRuntimeException("申請令牌失敗}AuthTokenauthToken=newAuthToken();authToken.setAccessToken((String)map.get("access_token"));authToken.setRefreshToken((String)map.get("refresh_token"));authToken.setJti((String)map.get("jti"));ken(),ttl,TimeUnit.SECONDS);return}privateStringgetHttpBasic(StringclientId,StringclientSecret)Stringvalue=byte[]encode=Base64Utils.encode(value.getBytes());return"Basic"+newString(encode);}} publicclass publicclassAuthControllerprivateAuthServiceprivateStringprivateStringprivate;privatepublicResultlogin(Stringusername,StringifthrownewRuntimeException("用戶名不存在}ifthrownew 不存在}AuthTokenauthToken=returnnewResult(true,StatusCode.OK,"登錄成功}privatevoid(String{HttpServletResponseresponse= }使用postman1Post請求當前在認證服務中,用戶是寫死在用戶認證類中。所以用戶登錄時,無論帳號輸入什么,只要是h都可以。因此需要動態(tài)獲取用戶帳號與.定義被接用戶微服務對外根據(jù)用戶名獲取用戶信息接publicUserfindUserInfo(@PathVariable("username")Stringusername){returnuserService.findById(username);}放行該接口,修改ResourceServerCon?g定義feign接publicinterfaceUserFeignpublicUserfindUserInfo(@PathVariable("username")String}認證服務添加依修改認證服務啟修改用戶認證@EnableFeignClients(basePackages=<version>1.0-測試測試:重新啟動服新建網(wǎng)關工程<artifactId>spring-cloud-starter-<artifactId>spring-cloud-starter-netflix-<artifactId>spring-cloud-starter-netflix-eureka-<!--redis--<artifactId>spring-boot-starter-data-redis-3)3)創(chuàng)建name:gateway-web'[/**]':#匹配所有請求allowedOrigins:"*"#跨域處理允許所有的域allowedMethods:#-id:changgou_goods_routeuri:lb://goodspublicclassWebGateWayApplicationpublicstaticvoidmain(String[]{}}#-StripPrefix=1id:changgou_user_routeuri:lb://user-id:changgou_oauth_useruri:lb://user-authhost:prefer-ip-address:trueenabled:trueinclude:true網(wǎng)關全局過濾新建過濾器類新建過濾器類AuthorizeFilter,業(yè)務邏輯2)判斷中是否存在信息,沒有的話publicpublicclassAuthFilterimplementsGlobalFilter,OrderedpublicstaticfinalStringAuthorization=privateAuthServicechain){//獲取當前請求對ServerHttpRequestrequest=excha
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 嘉定百聯(lián)母親節(jié)活動方案
- 嘉祥紋身活動方案
- 園本研修活動方案
- 商場營地活動方案
- 團員送溫暖活動方案
- 圖書捐贈交換活動方案
- 啤酒創(chuàng)意活動策劃方案
- 商城消防活動方案
- 周末餐飲小活動方案
- 百科知識競賽試題及答案
- AQ6111-2023個體防護裝備安全管理規(guī)范
- 重慶市大足縣2023-2024學年四年級數(shù)學第二學期期末聯(lián)考試題含解析
- 合伙人退出協(xié)議書
- (高清版)DZT 0208-2020 礦產(chǎn)地質勘查規(guī)范 金屬砂礦類
- 大件吊裝運輸企業(yè)信息化建設愿景
- 2024年春江蘇開放大學先進制造技術第一次過程性考核作業(yè)答案
- 2019版新人教版高中英語必修+選擇性必修共7冊詞匯表匯總(帶音標)
- FANUC數(shù)控系統(tǒng)連接與調試實訓 課件全套 第1-8章 FANUC 0iD硬件結構與連接-主軸控制
- 擴心病的健康宣教
- 日常網(wǎng)絡安全檢查記錄表模板
- 公務員午休管理制度
評論
0/150
提交評論