一. 流程
- 用戶發(fā)起獲取token的請求。
- 過濾器會驗證path是否是認(rèn)證的請求/oauth/token牵现,如果為false瞎疼,則直接返回沒有后續(xù)操作贼急。
- 過濾器通過clientId查詢生成一個Authentication對象太抓。
- 然后會通過username(clientId)和生成的Authentication對象生成一個UserDetails對象走敌,并檢查用戶是否存在掉丽。
- 以上全部通過會進入地址/oauth/token机打,即TokenEndpoint的postAccessToken方法中残邀。
- postAccessToken方法中會驗證Scope驱闷,然后驗證是否是refreshToken請求等空另。
- 之后調(diào)用AbstractTokenGranter中的grant方法扼菠。
- 然后通過DefaultTokenServices類從tokenStore中獲取OAuth2AccessToken對象循榆。
然后將OAuth2AccessToken對象包裝進響應(yīng)流返回秧饮。
二. 源碼執(zhí)行流程
2.1 發(fā)起獲取token請求/oauth/token
,必須帶上客戶端憑證Authorization
客戶端憑證值的格式為
Basic空格 + client_id:client_secret
經(jīng)過Base64加密后的值, 例如:
Authorization: Basic YWstaGx3eXk6YWtobQQQQ==
2.2 請求經(jīng)過攔截器BasicAuthenticationFilter
進行攔截授權(quán)處理
-
請求先經(jīng)過攔截器
org.springframework.security.web.authentication.www.BasicAuthenticationFilter#doFilterInternal
, 調(diào)用方法org.springframework.security.web.authentication.www.BasicAuthenticationConverter#convert
解析客戶憑證,獲取到client_id
和client_secret
,然后返回UsernamePasswordAuthenticationToken
-
跟據(jù)
UsernamePasswordAuthenticationToken
找到對應(yīng)的AuthenticationProvider
進行下一步處理
調(diào)用方法
org.springframework.security.authentication.ProviderManager#authenticate
遍歷所有的AuthenticationProvider
找到對應(yīng)的Provider
處理,UsernamePasswordAuthenticationToken
對應(yīng)的Provider
是org.springframework.security.authentication.dao.DaoAuthenticationProvider
-
調(diào)用方法
org.springframework.security.authentication.dao.DaoAuthenticationProvider#retrieveUser
根據(jù)client_id
和UsernamePasswordAuthenticationToken
獲取UserDetails
-
UserDetails
是調(diào)用方法org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService#loadUserByUsername
獲取的
-
調(diào)用方法
org.springframework.security.authentication.dao.DaoAuthenticationProvider#additionalAuthenticationChecks
根據(jù)UserDetails
和Authentication
校驗客戶憑證的client_secret
是否正確
以上步驟全部成功,就會執(zhí)行到下步驟
2.3 正式執(zhí)行/oauth/token
的業(yè)務(wù)方法
org.springframework.security.oauth2.provider.endpoint.TokenEndpoint#postAccessToken
-
調(diào)用方法
org.springframework.security.oauth2.provider.OAuth2RequestValidator#validateScope(TokenRequest, ClientDetails)
驗證scope
-
調(diào)用
org.springframework.security.oauth2.provider.CompositeTokenGranter#grant
根據(jù)grantType
遍歷所有的TokenGranter
, 找到對應(yīng)的TokenGranter
進行處理
調(diào)用
org.springframework.security.oauth2.provider.token.DefaultTokenServices#createAccessToken(org.springframework.security.oauth2.provider.OAuth2Authentication)
生成token信息