在職加薪基礎項目-歸檔第16天-講義spring security oauth2v_第1頁
在職加薪基礎項目-歸檔第16天-講義spring security oauth2v_第2頁
在職加薪基礎項目-歸檔第16天-講義spring security oauth2v_第3頁
在職加薪基礎項目-歸檔第16天-講義spring security oauth2v_第4頁
在職加薪基礎項目-歸檔第16天-講義spring security oauth2v_第5頁
已閱讀5頁,還剩35頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

學成-第16天-講義-SpringSecurityOauth2用戶認證需求截至目前,項目已經完成了學習功能,用戶通過學習頁面點播進行學習。如何去記錄學生的學習過程呢?要想掌握學生的學習情況就需要知道用戶的,記錄哪個用戶在什么時間學習什么課程;如果用戶要購買課程也需要知道用戶的。所以,去管理學生的學習過程最基本的要實現(xiàn)用戶的認證。用戶認證通過后去系統(tǒng)的資源,系統(tǒng)會判斷用戶是否擁有資源的權限,只允許限的系統(tǒng)資源,限的資源將無法,這個過程叫用戶。本項目包括多個子項目,如:學習系統(tǒng),教學、系統(tǒng)等,為了提高用戶體驗性需要實現(xiàn)用戶只證一次便可以在多個擁有權限的系統(tǒng)中,這個功能叫做單點登錄。百科:單點登錄(SingleSignOn 簡稱為SSO,是目前比較流行的企業(yè)業(yè)務整合的解決方案之一。下圖是SSO的示意圖,用戶登錄學成網一次即可多個系統(tǒng)1.31.3 不屬于本系統(tǒng),本系統(tǒng)并沒有用戶的賬號、等信息,本系統(tǒng)如果要獲取該用戶的基本信息則需要首先通 的認證系統(tǒng) 認證)進行認證 認證通過后本系統(tǒng)便可獲取 用戶基本信息,從而在本系統(tǒng)將 用戶的頭像、昵稱等信息顯示出來,該用戶便不用在本系統(tǒng)卻可以直接學習什么是第認證(跨平臺認證 用戶認證技術單點登錄的特點1、ApacheShiro.2、3、SpringsecurityOauth2Oauth2認證流第認證技術方案最主要是解決認證協(xié)議的通用標準問題,因為要實現(xiàn)跨系統(tǒng)認證,各系統(tǒng)之間要遵循一定的AUH協(xié)議為用戶資源的提供了一個安全的、開放而又簡易的標準。同時,任何第都可以使用AU認證服務,任何服務提供商都可以實現(xiàn)自身的AUH認證服務,因而AUH是開放的。業(yè)界提供了AUH現(xiàn)如PP、JavScip,Java,Ry等各種語言開發(fā)包,大大節(jié)約了程序員的時間,因而AUH是簡易的。互聯(lián)網很多服務如OpnAP,很多大公司如,aho,等都提供了AUH認證服務,這些都足以說明AUH標準逐漸成為開放資源的標準。Oath協(xié)議目前發(fā)展到.版本,.0版本過于復雜,2.版本已得到廣泛應用。參考:tts /ite/At/ fr=ladinOauth協(xié)議 認證的過程1、客戶端請求用戶進入程序的登錄頁面,點 的圖標 里信息的資源擁有者點擊 ,此時用戶掃 會對資源擁有者的進行驗證,驗證通過后,微信會詢問用戶是否給程序員自己的 頒發(fā)一個碼,并重定向到程序員的。3、客戶端獲取到碼,請求認證服務器申請令認證服務器驗證了客戶端請求的碼,如果合法則給客戶端頒發(fā)令牌,令牌是客戶端資源的通行證此交互過程用戶看不到,當客戶端拿到令牌后,用戶在程序員看到已經登錄成功??蛻舳藬y帶令牌資源服務器的資源程序員攜帶令牌請求服務器獲取用戶的基本信息服務器來校驗令牌的。引自Oauth2.0協(xié)議rfc6749 學成Androd客戶端、學成在 3、服務器(也稱認證服務器用來對資源擁有的進行認證、對資源進行。客戶端要想資源需要通過認證服務器由資源擁有者權后方可。資源的服務器,比如,學成網用戶管理服務器了學成網的用戶信息,學成網學習服務器了學生的學信息, 的資源服務了 的用戶信息等??蛻舳俗罱K資源服務器獲取資源信息。Oauth2在本項目的應Oath2是一個標準的開放的協(xié)議,應用程序可以根據(jù)自己的要求去使用Oauth2,本項目使用Oauth2下目標:3、學成前端(客戶端)學成微服務的資源SpringsecurityOauth2本項目采用Springsecurity+Oauth2完成用戶認證及用戶,Springsecurity是一個強大的和高度可定制的身份驗證和控制框架,Springsecurity框架集成了Oauth2協(xié)議,下圖是項目認證架構圖:2、認證服務下發(fā)用戶令牌,擁有令牌表示合法 如果合法則放行繼續(xù)6、資源服務完成則響應資源信息SpringSecurityOauth2本項目認證服務基于SpringSecurityOauth2進行構建,并在其基礎上作了一些擴展,采用JWT令牌機制,并自定義了用戶的內容。本的主要目標是學項目中集成SpringSecurityOauth2的方法和流程,通過springSecurityOauth2的研究需要達到以下目標:2、理解springSecurityOauth23、掌握資源服務集成 導入基礎工 下的xc-service-ucenter-auth工程,該工程是基于SpringSecurityOauth2的一個二次封裝的工創(chuàng)建數(shù)據(jù)導入資 下的xc_user.sql,創(chuàng)建用戶數(shù)據(jù)以“oauth_”開頭的表都是springSecurity自帶的本項目中springSecurity主要使用oauth_client_detailsclient_id:客戶端idresource_ids:資源id(暫時不用)client_secret:客戶端scope:范圍authorized_grant_type:類型Oauth2模碼模式(AuthorizationCode)隱式模式(Implicit)模式(ResourceOwnerPasswordCredentials)客戶端模式(ClientCredentials)其中碼模式和模式應用較多,本小節(jié)介紹碼模式碼流 認證的過程就是碼模式,流程如下1、客戶端請求第2、用戶(資源擁有者)同意給客戶端3、客戶端獲取到碼,請求認證服務器申請令牌4、認證服務器向客戶端響應令牌5、客戶端請求資源服務器的資源 資源服務校驗令牌,完成申請請求認證服務獲取碼參數(shù)列表如下response_type:碼模式固定為scop:客戶端范圍,和配置類中設置的scop一致首先跳轉到登錄頁面SngSecuty接收到請求會調用UsrDtisService接口的laUsrByUsr方法查詢用戶正確的。當前導入的基礎工程中將正確的硬編碼為“123,所以這里賬號隨意輸入,輸入12即可認證通過。認證服務攜帶碼跳轉申請令拿到碼后,申請令牌Post請求:hos參數(shù)如下erct_i:申請碼時的跳轉ul,一定和申請碼時用的riec_ui一致。此需使用pBsc認。什么是httpBasicttp協(xié)議定義的一種認證方式,將客戶端id和客戶端按照客戶端D:客戶端”的格式拼接,并用ase64編碼,放在heaer中請求服務端,一個例子:Authorization:Basic認證失敗服務端返回401Unauthorizedhttpbasic點擊發(fā)送申請令牌成功token_type:有MACToken與BearerToken兩種類型,兩種的校驗算法不同,RFC6750建議Oauth2采用Bearer 資源服資源服務流 客戶端攜帶令牌資源服務,如果令牌合法則可成功資源服務中的資上圖的業(yè)務流程如下3、客戶端攜帶令牌資源服客戶端在Httpheader中添加:Authorization:Bearer資源服務接收到令牌,使用公鑰校驗令牌的資源服務配基本上所有微服務都是資源服務,這里我們在課程管理服務上配置控制,當配置了控制后如要課程信1、配置公 對外向資源服務提供公鑰,資源服務使用公鑰來校驗令牌的。 2、添加依<groupId>org.spri<artifactId>spring‐c@EnableGlobalMethodSecurity(prePostEnabled=true,securedEnabled=true)//激活方法上PreAuthorize注publicclassResourceServerConfigextendsResourceServerConfigurerAdapter//privatestaticfinalStringPUBLIC_KEY=publicTokenStoretokenStore(JwtAccessTokenConverter{returnnew}publicJwtAccessTokenConverter{JwtAccessTokenConverterconverter=newJwtAccessTokenConverter();return}獲取非對稱加密公鑰@return公鑰privateStringgetPubKey()Resourceresource=newClassPathResource(PUBLIC_KEY);try{InputStreamReaderinputStreamReader=newBufferedReaderbr=newBufferedReder(inputStreamReader);returnbr.lines().collect(Collectors.joining("\n");}catch(IOException{return}}//Http安全配置,對每個到達系統(tǒng)的ttp請 進行校publicvoidconfigure(HttpSecurityhttp)throwsException//所有請求必須認證通}}資源服務測這里我們測試課程查get{{"error":"error_description":"Fullauthenticationisrequiredtoaccessthis}請求時攜帶令牌在httpheader中添加Authorization:Bearer解決swagger-ui當課程管理加了之后再swagger-ui則報錯修改配置類ResorceSevrCn?g的cn?gre方法:針對swagr-i的請求路徑進行放行://Http//Http安全配置,對每個到達系統(tǒng)的http請 進行校publicvoidconfigure(HttpSecurityhttp)throwsException//所有請求必須認證通//下邊的路徑.antMatchers("/v2/api‐docs","/swagger‐resurces/cofiguration/ui","/swagger‐resources","/swagger‐resources/configuration/ecurity","/swagger‐}注意通過上邊的配置雖然可以swgr-i,但是無法進行單元測試,除非去掉認證的配置或在上邊配置中添加所有請求均放行("/**")。3.43.4模式(ResourceOwnerPasswordCredentials)與碼模式的區(qū)別是申請令牌不再使用碼,而是直接并且此需要使用httpBasic認證上邊參數(shù)使用x-www-form-urlencoded方式傳輸,使用postmanSpringSecurityOauth2提供校驗令牌的端Get:參數(shù)token使用postman結果如下{{"companyId":"userpic":null,"user_name":"mrt","scope":["name":"utype":"id": "jti":"client_id":}exp:過期時間,long類型,距離1970年的秒數(shù)(newDate().getTime()可得到當前時間距離1970年的毫秒數(shù))。user_name:用戶名client_id:客戶端Id,在oath_client_details中配置scope:客戶端范圍在oauth_client_details表中配置 、ameutype、id:這些字段是本認證服務在SpringSecurity基礎上擴展的用戶刷新令牌是當令牌快過期時重新生成一個令牌,它于碼和生成令牌不同,刷新令牌不需要碼也不需要賬號和,只需要一個刷新令牌、客戶端i和客戶端。測試如下:grant_type:固定為JWTJWT問題傳統(tǒng)方法的問題是用戶每次請求資源服務,資源服務都需要攜帶令牌認證服務去校驗令牌的,并據(jù)令牌獲取用戶的相關信息,性能低下。解決什么是JSONebon(JWT)是一個開放的行業(yè)標準(RFC7519),它定義了一種簡介的、自包含的協(xié)議格式,用于在通信雙方傳遞json對象,傳遞的信息經過數(shù)字簽名可以被驗證和信任。JWT可以使用HMC算法或使用SA的公鑰/私鑰對來簽名,防止被篡改。標準:1、JWT令牌較長,占空間比較大頭部包括令牌的類型(即JWT)及使用的哈希算法(如HMACSHA256或RSA){{"alg":"typ":}第二部分是負載,內容也是一個js對象,它是存放有效信息的地方,它可以存放jw提供的現(xiàn)成字段,比如:iss(簽發(fā)者),xp(過期時間戳),su(面向的用戶)等,也可自定義字段。最后將第二部分負載使用Base64Ur編碼,得到一個字符串就是JWT令牌的第二部分。{{"sub": "name":456","admin":tue}這個部分使用ase4rl將前兩部分進行編碼,編碼后使用點()連接組成字符串,最后使用hadr中簽名算法進行簽名。一個例子base64UrlEncode(header)+"."+base64UrlEncode(header):jwt令牌的第一部分。base64UrlEncode(payload):jwt令牌的第二部分。JWTSpringSecurity提供對JWT的支持,本節(jié)我們使用SpringSecurity提供的wHlr來創(chuàng)建JWT令牌,校驗JWT令牌下邊命令生成密鑰,采用RSA算法每個包含公鑰和私keytool-genkeypair-aliasxckey-keyalgRSA-keypassxuecheng-keystorexc.keystore-storepassKeytool是一個java提供的管理工-keypass:密鑰查詢信息keytool-list-keystorxc.keyst刪除keytool-delete-aliasxckey-keystore2、導出公安 安裝資 keytoolkeytool‐list‐rfc‐‐keystorexc.keystore|opensslx509‐informpem下邊這一段就是公鑰內容-----BEGINPUBLICKEY----- PgLnbQczBHbBug6uOr78qnWsYxHlW6Aa5dI5NsmOD4DLtSw8eX0hFyK5Fmz2yMJePDqUi0JYS2r0iIo7n8vN7s83v5uOQIDAQAB-----ENDPUBLICKEY-----生成jwt令publicvoid 文Stringkey_location=//密鑰Stringkeystore_password= 路ClassPathResourceresource=new//密鑰工KeyStoreKeyFactorykeyStoreKeyFactory=newKeyStoreKeyFactory(resource,//密鑰 , 和別名要匹StringStringkeypassword=//Stringalias=//密鑰對(密鑰和公鑰KeyPairkeyPair=RSAPrivateKeyaPrivate=(RSAPrivateKey)Map<String,Object>tokenMap=newHashMap<>();tokenMap.put("id","123");tokenMap.put("name",tokenMap.put("roles",tokenMap.put("ext",//生成jwtJwtjwt=JwtHelper.encode(JSON.toJSONString(tokenMap),new//取出jwtStringtoken=jwt.getEncoded();}驗證jwt令////資源服務使用公鑰驗證jwt ,并對publicvoidStringtoken48pJB5f‐le2zgYMqR1L2LyTmrbRdRxkrQfsa1j8IW2T4eUiN3f9wF9JxUK1//Stringpublicky="‐‐‐‐‐BEGINPUBLIC OQIDAQAB‐‐‐‐‐ENDPUBLICKEY‐‐‐‐‐";//校驗Jwtjwt=JwtHelper.decodeAndVerify(token,new//獲取jwt原始Stringclaims=//jwt令Stringencoded=jwt.getEncoded();}認證接口開用戶登錄的流程執(zhí)行流程 、由于jwt令牌過長,不宜在 中,所以將jt令牌在i,由客戶端請求服務端獲取并在客戶端存儲。Redis配安裝1、安裝Redis服 redis‐serverredis‐server出現(xiàn)下圖說明redisredis‐serverredis‐server‐‐service‐installredis.windows‐service.conf‐‐loglevel 卸載服務:redis-server.exe--service-開啟服務:redis-server.exe--service-停止服務:redis-server.exe--service-2、redis-desktop- 連接成功redis連接配name:host:${REDIS_HOST:}port:${REDIS_PORT:6379}timeout:5000#連接超時毫秒maxActive:maxIdle:minIdle:maxWait:‐1#連接池最大等行時間‐1沒有限制測publicclassRedisTest{privateStringRedisTemplatestringRedisTemplate;publicvoid//定義Stringkey=//定義Map<String,String>mapValue=newHashMap<>(); Stringvalue=//向redis 字符stringRedisTemplate.boundValueOps(key).set(value,60, 過期時間,已過期返回Longexpire=//根據(jù)key獲取Strings=stringRedisTemplate.opsForValue().get(key);}}需求分認證服務需要實現(xiàn)的功能如1、登錄接前端pst提交賬號、等,用戶校驗通過,生成令牌,并將令牌到i。將令牌寫入。2、退出接刪除中的令牌業(yè)務流程如下Api接@Api(value="@Api(value="用戶認證",description="用戶認證接口")publicinterfaceAuthControllerApi{@ApiOperation("登錄publicLoginResultlogin(LoginRequest@ApiOperation("退出publicResponseResult}配置參在application.ymltokenValiditySeconds:1200 到redis的過期時clientId:XcWebAppclientSecret:XcWebApp:MaxAge:申請令牌測為了不破壞SigSecuity的代碼,我們在Sric方法中通過Rstemlat請求SpngSecuiy所的申請令牌接口來申請令牌,下邊是測試代碼:publicclassTestClient{LoadBalancerClientRestTemplatepublicvoid//采用客戶端負載均衡,從eureka獲取認證服務的ip和端ServiceInstanceserviceInstance=URIuri=StringauthUrl=//URIurl,HttpMethodmethod,HttpEntity<?>requestEntity,Class<T>//url就是申請令牌的url//methodhttp的方法類//requestEntity//responseType,將響應的結果生成的類//請求的內容//1、header信息,包括了httpbasicMultiValueMap<String,String>headers=newLinkedMultiValueMap<String,String>();Stringhttpbasic=httpbasic("XcWebApp","XcWebApp");//"Basicheaders.add("Authorization",//2、包括:grant_type、username、MultiValueMap<String,String>body=newLinkedMultiValueMap<String,String>(); HttpEntity<MultiValueMap<String,String>>multiValueMapHttpEntity=newHttpEntity<MultiValueMap<String,String>>(body,headers);//指 restTemplate當遇到400或401響應時候也不要拋出異常,也要正常返回restTemplate.setErrorHandler(newDefaultResponspublicvoidhandleError(ClientHttpRespnseesponse)throwsIOException//當響應的值為400或401時候也要正常響應,不要拋出異if(response.getRawStatusCode()!=400&&respnsegetRawStatusCode()!=401){}} 調用申請令ResponseEntity<Map>exchange=restTemplate.exchange(authUrl,HttpMethod.POST,multiValueMapHttpEntity,Map.class);Mapbody1=exchange.getBody();}privateStringhttpbasic(StringclientId,String//將客戶端id和客戶 拼接,按“客戶端id:客戶 Stringstring=//進行base64編byte[]encode=Base64.encode(string.getBytes());return"Basic"+newString(encode);}}調用認證服務申請令牌,并將令牌到redis。創(chuàng)建AuthToken模型類,申請的令牌,包括令牌、刷新令牌、jwt令牌publicclassAuthToken{Stringaccess_token;//tokenStringrefresh_token;//刷新tokenStringjwt_token;//jwt令牌}publicclassAuthServiceprivatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(AuthService.class);intRestTemplaterestTemplate;LoadBalancerClientloadBalancerClient;StringRedisTemplate//認證方publicAuthTokenlogin(Stringusername,Stringpassword,StringclientId,String//申請令AuthTokenauthToken=applyToken(username,password,clientId,clientSecret);if(authToken==null){}//將 到Stringaccess_token=authToken.getAccess_token();Stringcontent=JSON.toJSONString(authToken);booleansaveTokenResult=saveToken(access_token,content,}return} 令牌到privatebooleansaveToken(Stringaccess_token,Stringcontent,long//令牌名Stringname="user_token:"+//保存到令牌到 //獲取過期時Longexpire=stringRedisTemplate.getExpire(name);returnexpire>0;}//認證方privateAuthTokenapplyToken(Stringusername,Stringpassword,StringclientId,String//選中認證服務的地ServiceInstanceserviceInstance=if(serviceInstance=={LOGGER.error("chooseanauthinstancefai}//獲取令牌的Stringpath=serviceInstance.getUri().toStrng()+//定義MultiValueMap<String,String>formData=new 方formData.add("grant_type",formData.add("password",//定義MultiValueMap<String,String>header=newLinkedMultiValueMap<>();header.add("Authorization",httpbasic(clientId,clientSecret));//指 restTemplate當遇到400或401響應時候也不要拋出異常,也要正常返回restTemplate.setErrorHandler(newpublicvoidhandleError(ClientHttpResponseresponse)throwsIOException//當響應的值為400或401時候也要正常響應,不要拋出異if(response.getRawStatusCode()!=400&&response.getRawStatusCode()!=401){}}Mapmap=null;try{//http請求springsecurity的申請令牌接ResponseEntity<Map>mapResponseEntity=restTemplate.exchange(path,newHttpEntity<MultiValueMap<String,String>>(formData,header),Map.class);map=mapResponseEntity.getBody();newHttpEntity<MultiValueMap<String,String>>(formData,header),Map.class);map=mapResponseEntity.getBody();}catch(RestClientException{LOGGER.error("requestoauth_token_passworderror:{}",e.getMessage());}if(map==nullmap.get("access_token")==null||map.get("refresh_token")==null||map.get("jti")==null){//jti是jwt令牌的唯一標識作為用 令}Auth

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論