亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

詳解SpringCloud服務認證(JWT)

2024-07-13 10:17:26
字體:
來源:轉載
供稿:網友

 - JWT

JWT(JSON Web Token), 是為了在網絡應用環境間傳遞聲明而執行的一種基于JSON的開放標準((RFC 7519).該token被設計為緊湊且安全的,特別適用于分布式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便于從資源服務器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用于認證,也可被加密。

- JWT與其它的區別

通常情況下,把API直接暴露出去是風險很大的,不說別的,直接被機器攻擊就喝一壺的。那么一般來說,對API要劃分出一定的權限級別,然后做一個用戶的鑒權,依據鑒權結果給予用戶開放對應的API。目前,比較主流的方案有幾種:

OAuth

OAuth(開放授權)是一個開放的授權標準,允許用戶讓第三方應用訪問該用戶在某一服務上存儲的私密的資源(如照片,視頻),而無需將用戶名和密碼提供給第三方應用。

OAuth 允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每一個令牌授權一個特定的第三方系統(例如,視頻編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth讓用戶可以授權第三方網站訪問他們存儲在另外服務提供者的某些特定信息,而非所有內容

Cookie/Session Auth

Cookie認證機制就是為一次請求認證在服務端創建一個Session對象,同時在客戶端的瀏覽器端創建了一個Cookie對象;通過客戶端帶上來Cookie對象來與服務器端的session對象匹配來實現狀態管理的。默認的,當我們關閉瀏覽器的時候,cookie會被刪除。但可以通過修改cookie 的expire time使cookie在一定時間內有效,基于session方式認證勢必會對服務器造成一定的壓力(內存存儲),不易于擴展(需要處理分布式session),跨站請求偽造的攻擊(CSRF)

- JWT的優點

1.相比于session,它無需保存在服務器,不占用服務器內存開銷。

2.無狀態、可拓展性強:比如有3臺機器(A、B、C)組成服務器集群,若session存在機器A上,session只能保存在其中一臺服務器,此時你便不能訪問機器B、C,因為B、C上沒有存放該Session,而使用token就能夠驗證用戶請求合法性,并且我再加幾臺機器也沒事,所以可拓展性好就是這個意思。

3.前后端分離,支持跨域訪問。

- JWT的組成

{ "iss": "JWT Builder",  "iat": 1416797419,  "exp": 1448333419,  "aud": "www.battcn.com",  "sub": "1837307557@qq.com",  "GivenName": "Levin",  "Surname": "Levin",  "Email": "1837307557@qq.com",  "Role": [ "ADMIN", "MEMBER" ] }
  1.  iss: 該JWT的簽發者,是否使用是可選的;
  2. sub: 該JWT所面向的用戶,是否使用是可選的;
  3. aud: 接收該JWT的一方,是否使用是可選的;
  4. exp(expires): 什么時候過期,這里是一個Unix時間戳,是否使用是可選的;
  5. iat(issued at): 在什么時候簽發的(UNIX時間),是否使用是可選的;
  6. nbf (Not Before):如果當前時間在nbf里的時間之前,則Token不被接受;一般都會留一些余地,比如幾分鐘;,是否使用是可選的;

Spring,Cloud,JWT,服務認證

一個JWT實際上就是一個字符串,它由三部分組成,頭部、載荷、簽名(上圖依次排序)

JWT Token生成器:https://jwt.io/

- 認證

Spring,Cloud,JWT,服務認證

- 登陸認證

  1. 客戶端發送 POST 請求到服務器,提交登錄處理的Controller層
  2. 調用認證服務進行用戶名密碼認證,如果認證通過,返回完整的用戶信息及對應權限信息
  3. 利用 JJWT 對用戶、權限信息、秘鑰構建Token
  4. 返回構建好的Token

Spring,Cloud,JWT,服務認證

- 請求認證

  1. 客戶端向服務器請求,服務端讀取請求頭信息(request.header)獲取Token
  2. 如果找到Token信息,則根據配置文件中的簽名加密秘鑰,調用JJWT Lib對Token信息進行解密和解碼;
  3. 完成解碼并驗證簽名通過后,對Token中的exp、nbf、aud等信息進行驗證;
  4. 全部通過后,根據獲取的用戶的角色權限信息,進行對請求的資源的權限邏輯判斷;
  5. 如果權限邏輯判斷通過則通過Response對象返回;否則則返回HTTP 401;

無效Token

Spring,Cloud,JWT,服務認證

有效Token

Spring,Cloud,JWT,服務認證

- JWT的缺點

有優點就會有缺點,是否適用應該考慮清楚,而不是技術跟風

  1. token過大容易占用更多的空間
  2. token中不應該存儲敏感信息
  3. JWT不是 session ,勿將token當session
  4. 無法作廢已頒布的令牌,因為所有的認證信息都在JWT中,由于在服務端沒有狀態,即使你知道了某個JWT被盜取了,你也沒有辦法將其作廢。在JWT過期之前(你絕對應該設置過期時間),你無能為力。
  5. 類似緩存,由于無法作廢已頒布的令牌,在其過期前,你只能忍受”過期”的數據(自己放出去的token,含著淚也要用到底)。

- 代碼(片段)

TokenProperties 與 application.yml資源的key映射,方便使用

@Configuration@ConfigurationProperties(prefix = "battcn.security.token")public class TokenProperties { /** * {@link com.battcn.security.model.token.Token} token的過期時間 */ private Integer expirationTime; /** * 發行人 */ private String issuer; /** * 使用的簽名KEY {@link com.battcn.security.model.token.Token}. */ private String signingKey; /** * {@link com.battcn.security.model.token.Token} 刷新過期時間 */ private Integer refreshExpTime; // get set ...}

Token生成的類

@Componentpublic class TokenFactory { private final TokenProperties properties; @Autowired public TokenFactory(TokenProperties properties) { this.properties = properties; } /** * 利用JJWT 生成 Token * @param context * @return */ public AccessToken createAccessToken(UserContext context) { Optional.ofNullable(context.getUsername()).orElseThrow(()-> new IllegalArgumentException("Cannot create Token without username")); Optional.ofNullable(context.getAuthorities()).orElseThrow(()-> new IllegalArgumentException("User doesn't have any privileges")); Claims claims = Jwts.claims().setSubject(context.getUsername()); claims.put("scopes", context.getAuthorities().stream().map(Object::toString).collect(toList())); LocalDateTime currentTime = LocalDateTime.now(); String token = Jwts.builder()  .setClaims(claims)  .setIssuer(properties.getIssuer())  .setIssuedAt(Date.from(currentTime.atZone(ZoneId.systemDefault()).toInstant()))  .setExpiration(Date.from(currentTime  .plusMinutes(properties.getExpirationTime())  .atZone(ZoneId.systemDefault()).toInstant()))  .signWith(SignatureAlgorithm.HS512, properties.getSigningKey()) .compact(); return new AccessToken(token, claims); } /** * 生成 刷新 RefreshToken * @param userContext * @return */ public Token createRefreshToken(UserContext userContext) { if (StringUtils.isBlank(userContext.getUsername())) {  throw new IllegalArgumentException("Cannot create Token without username"); } LocalDateTime currentTime = LocalDateTime.now(); Claims claims = Jwts.claims().setSubject(userContext.getUsername()); claims.put("scopes", Arrays.asList(Scopes.REFRESH_TOKEN.authority())); String token = Jwts.builder()  .setClaims(claims)  .setIssuer(properties.getIssuer())  .setId(UUID.randomUUID().toString())  .setIssuedAt(Date.from(currentTime.atZone(ZoneId.systemDefault()).toInstant()))  .setExpiration(Date.from(currentTime  .plusMinutes(properties.getRefreshExpTime())  .atZone(ZoneId.systemDefault()).toInstant()))  .signWith(SignatureAlgorithm.HS512, properties.getSigningKey()) .compact(); return new AccessToken(token, claims); }}

配置文件,含token過期時間,秘鑰,可自行擴展

battcn: security: token: expiration-time: 10 # 分鐘 1440 refresh-exp-time: 30 # 分鐘 2880 issuer: http://blog.battcn.com signing-key: battcn

WebSecurityConfig 是 Spring Security 關鍵配置,在Securrty中基本上可以通過定義過濾器去實現我們想要的功能.

@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { public static final String TOKEN_HEADER_PARAM = "X-Authorization"; public static final String FORM_BASED_LOGIN_ENTRY_POINT = "/api/auth/login"; public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**"; public static final String MANAGE_TOKEN_BASED_AUTH_ENTRY_POINT = "/manage/**"; public static final String TOKEN_REFRESH_ENTRY_POINT = "/api/auth/token"; @Autowired private RestAuthenticationEntryPoint authenticationEntryPoint; @Autowired private AuthenticationSuccessHandler successHandler; @Autowired private AuthenticationFailureHandler failureHandler; @Autowired private LoginAuthenticationProvider loginAuthenticationProvider; @Autowired private TokenAuthenticationProvider tokenAuthenticationProvider; @Autowired private TokenExtractor tokenExtractor; @Autowired private AuthenticationManager authenticationManager; protected LoginProcessingFilter buildLoginProcessingFilter() throws Exception { LoginProcessingFilter filter = new LoginProcessingFilter(FORM_BASED_LOGIN_ENTRY_POINT, successHandler, failureHandler); filter.setAuthenticationManager(this.authenticationManager); return filter; } protected TokenAuthenticationProcessingFilter buildTokenAuthenticationProcessingFilter() throws Exception { List<String> list = Lists.newArrayList(TOKEN_BASED_AUTH_ENTRY_POINT,MANAGE_TOKEN_BASED_AUTH_ENTRY_POINT); SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(list); TokenAuthenticationProcessingFilter filter = new TokenAuthenticationProcessingFilter(failureHandler, tokenExtractor, matcher); filter.setAuthenticationManager(this.authenticationManager); return filter; } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(AuthenticationManagerBuilder auth) { auth.authenticationProvider(loginAuthenticationProvider); auth.authenticationProvider(tokenAuthenticationProvider); } @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() // 因為使用的是JWT,因此這里可以關閉csrf了 .exceptionHandling() .authenticationEntryPoint(this.authenticationEntryPoint) .and()  .sessionManagement()  .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and()  .authorizeRequests()  .antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll() // Login end-point  .antMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point .and()  .authorizeRequests()  .antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() // Protected API End-points  .antMatchers(MANAGE_TOKEN_BASED_AUTH_ENTRY_POINT).hasAnyRole(RoleEnum.ADMIN.name()) .and()  .addFilterBefore(buildLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class)  .addFilterBefore(buildTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class); }}

- 說點什么

由于JWT代碼做了簡單封裝,包含內容較多,所以文章里只貼主要片段,需要完整代碼可以直接從GIT獲取

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲成人xxx| 欧美激情一区二区三级高清视频| 最近中文字幕mv在线一区二区三区四区| 久久精品国产亚洲一区二区| 亚洲黄色有码视频| 日韩av第一页| 91av在线不卡| 一本色道久久88综合亚洲精品ⅰ| 亚洲韩国日本中文字幕| 色av中文字幕一区| 黄网动漫久久久| 日本久久久久久| 57pao成人永久免费视频| 亚洲精品国产欧美| 国产精品福利观看| 亚洲热线99精品视频| 国产亚洲精品美女久久久| 亚洲无限乱码一二三四麻| 国产综合在线视频| 国产亚洲欧洲高清一区| 亚洲午夜av电影| 国产区精品在线观看| 欧美中文字幕视频| 午夜欧美不卡精品aaaaa| 欧美性高潮在线| 国产精品一区专区欧美日韩| 亚洲qvod图片区电影| 久久久国产视频91| 91亚洲精品视频| 欧美视频在线免费看| 最新国产精品拍自在线播放| 国产精品久久久久久久久久小说| 亚洲国产一区二区三区在线观看| 综合国产在线视频| 国产精品av在线| 久久网福利资源网站| 欧美成人午夜免费视在线看片| 久久久久五月天| 久久久精品在线| 亚洲精品在线91| 91国偷自产一区二区三区的观看方式| 欧美激情二区三区| 日韩在线视频网| 午夜欧美大片免费观看| 欧美激情在线视频二区| 午夜精品一区二区三区av| 久久男人av资源网站| 亚洲**2019国产| 日韩男女性生活视频| 日韩在线播放一区| 亚洲一级一级97网| 51精品国产黑色丝袜高跟鞋| 亚洲a成v人在线观看| 自拍亚洲一区欧美另类| 91av在线网站| 狠狠躁夜夜躁久久躁别揉| 一本色道久久综合狠狠躁篇怎么玩| 中文字幕久精品免费视频| 欧美一级免费视频| 97超视频免费观看| 日韩av在线免费| 亚洲va欧美va国产综合剧情| 5252色成人免费视频| 亚洲国产精品999| 国产三级精品网站| 亚洲最大福利视频网站| 亚洲一区www| 成人h视频在线观看播放| 亚洲自拍偷拍一区| 欧美性少妇18aaaa视频| 欧美日韩在线视频一区二区| 亚洲最大成人免费视频| 人人做人人澡人人爽欧美| 成人深夜直播免费观看| 久久精品视频播放| 欧美又大又粗又长| 日韩风俗一区 二区| 国产精品青青在线观看爽香蕉| www.99久久热国产日韩欧美.com| 久久精品福利视频| 国产在线一区二区三区| 国产一区二区三区视频| 日韩精品免费在线视频| 日韩一区二区av| 一本色道久久综合亚洲精品小说| 国产精品欧美激情在线播放| 久久免费少妇高潮久久精品99| 欧美中文字幕视频| 欧美裸体xxxx极品少妇软件| 国产精品亚洲美女av网站| 91中文字幕在线观看| 韩国视频理论视频久久| 欧美成人激情视频免费观看| 91爱爱小视频k| 亚洲毛茸茸少妇高潮呻吟| 成人美女免费网站视频| 一区二区福利视频| 亚洲一区二区三区xxx视频| 精品毛片三在线观看| 91av在线播放视频| 精品国产乱码久久久久酒店| 欧美老女人bb| 亚洲一区二区少妇| 亚洲天堂网在线观看| 日韩精品在线观看一区二区| 欧美日韩国产在线| 亚洲欧美成人一区二区在线电影| 色婷婷久久av| 亚洲第一精品夜夜躁人人躁| 亚洲精品日韩丝袜精品| 欧美极品少妇xxxxⅹ喷水| 欧美亚洲免费电影| 中文字幕日韩欧美在线视频| 都市激情亚洲色图| 亚洲欧洲午夜一线一品| 成人国产亚洲精品a区天堂华泰| 亚洲欧洲成视频免费观看| 日韩av资源在线播放| 亚洲视频在线观看| 日韩在线视频一区| 成人国产精品日本在线| 日本精品在线视频| 精品香蕉一区二区三区| 欧美激情一区二区三区高清视频| 国产男女猛烈无遮挡91| 日韩成人在线观看| 欧美激情亚洲自拍| 国产精品91免费在线| 日韩av片永久免费网站| 久久九九有精品国产23| 亚洲九九九在线观看| 亚洲专区中文字幕| 久久九九精品99国产精品| 福利视频第一区| 国产一区在线播放| 欧美激情区在线播放| 美女久久久久久久| 成人性生交xxxxx网站| 日韩av中文在线| 国产亚洲精品久久久久久777| 亚洲性生活视频在线观看| 精品国产福利视频| 一区二区成人av| 亚洲精品美女在线观看| 国产日韩欧美日韩| 日韩专区中文字幕| 日韩中文综合网| 亚洲精品电影网站| 亚洲2020天天堂在线观看| 亚洲视频欧洲视频| 亚洲成人a**站| 欧美黑人性生活视频| 亚洲精品国产精品自产a区红杏吧| 综合激情国产一区| 97色在线观看免费视频| 亚洲在线免费视频| 91在线观看免费网站| 欧美激情视频网址| 久久综合久久88| 久久久久久尹人网香蕉| 精品亚洲永久免费精品| 久久久久国产精品免费| 亚洲欧美综合图区| 久久久噜噜噜久久中文字免|