OAuth2AuthenticationToken
authenticated=true 认证后安全上下文实际保存的OAuth2用户认证,由convert将填充后的OAuth2LoginAuthenticationToken转换而来。
OAuth2AuthorizationRequestRedirectFilter
通过调用OAuth2AuthorizationRequestResolver用于判断是否为授权请求(默认为 "/oauth2/authorization/{registrationId}",可通过.oauth2Login().authorizationEndpoint().baseUri()配置) ,并且请求包装为OAuth2AuthorizationRequest后由authorizationRequestRepository(默认基于SESSION实现)将授权请求保存(后有他用)
随后重定向到追加了参数(client-id、response_type)的真实授权码请求。
OAuth2LoginAuthenticationFilter
继承自AbstractAuthenticationProcessingFilter,即负责身份认证的Filter。
当是loginProcessingUrl(默认为/login/oauth2/code/*)请求且带了code和state时,尝试以这俩参数构建OAuth2LoginAuthenticationToken且调用AuthenticationManager去进行认证。
认证通过后,调用authenticationResultConverter将认证后完全填充的OAuth2LoginAuthenticationToken转为authenticated=true的OAuth2AuthenticationToken,用以代表认证后的身份。(该converter默认就是直接提取填充后的"principal、authorities、clientid"直接new)
将先前得到 "token、refreshToken" 等信息包装为OAuth2AuthorizedClient调用 OAuth2AuthorizedClientRepository#saveAuthorizedClient保存起来(默认是基于内存实现的ClientId和Principal为key的Map)
OAuth2AuthorizationCodeGrantFilter
(该Filter,在oauth2Login()下会永远被跳过,因为该请求已被OAuth2LoginAuthenticationFilter处理后通过successHandler重定向)
匹配带code与state的请求(表示回调请求)且满足authorizationRequestRepository.loadAuthorizationRequest不为空时(表示经过了RedirectFilter,是先前授权请求发起的),会构造 OAuth2AuthorizationCodeAuthenticationToken交由AuthenticationManager(背后交由OAuth2AuthorizationCodeAuthenticationProvider)进行认证,并将结果构造为OAuth2AuthorizedClient交由authorizedClientRepository保存,然后去除参数再将请求重定向到 "savedRequest 或者 redirect-url"。
【注:不是很能理解该Filter这里为什么要重定向,这个重定向真的很恼火。如果API自身需要code,这重定向把参数清除了会报错;而即便API不要code了依附于它的逻辑使用authorizedClientRepository,那也是无意义多一次请求。而且其基于SESSION的实现本来没什么问题,但非要重定向请求一次就导致单纯的多实例时会存在问题】
OAuth2LoginAuthenticationProvider
对OAuth2LoginAuthenticationToken尝试认证,其内会进一步构造OAuth2AuthorizationCodeAuthenticationToken,然后调用 OAuth2AuthorizationCodeAuthenticationProvider 对其进行认证。
经过上述认证后拿到填充了 "access_token" 的OAuth2AuthorizationCodeAuthenticationToken,会构造成OAuth2UserRequest后传给OAuth2UserService负责进行实际的 "user-info-uri" 请求,并将结果包装成DefaultOAuth2User返回。(该User拥有两类authorities,一个是ROLE_USER(Spring在经过oauth2UserService时手动添加的),一类是Token中的SCOPE_{sopces})
OAuth2AuthorizationCodeAuthenticationProvider
对OAuth2AuthorizationCodeAuthenticationToken尝试认证,内部会构造对"token-uri"的实际请求,并调用DefaultAuthorizationCodeTokenResponseClient进行请求返回,并根据返回结果OAuth2AccessTokenResponse(内含access_token/refreash_token),新new一个填充了"access_token"的OAuth2AuthorizationCodeAuthenticationToken返回。
由 org.springframework.boot:spring-boot-starter-oauth2-resource-server 引入,提供对请求中携带token校验解析、身份认证的服务。
2. 必须的配置JwtDecoder:在oauth2ResourceServer的Configurer::init时,会构建JwtAuthenticationProvider,它就需要decorder以提供对"token"校验解析。
JwtEncoder:虽然不是必须的,但我们自己系统登录有令牌分发的需要。
3. 相关 Filter
BearerTokenAuthenticationFilter
(虽没继承AbstractAuthenticationProcessingFilter但却干着认证的事)
首先通过DefaultBearerTokenResolver::resolve判断是否含"token",然后构建BearerTokenAuthenticationToken并调用AuthenticationManager尝试认证。
将认证后的结果JwtAuthenticationToken设置到安全上下文中。如果中途出现了异常,则以该filter的authenticationEntryPoint(可通过.oauth2ResourceServer().authenticationEntryPoint配置) 处理。
BearerTokenAuthenticationToken
代表原始token的一个过渡身份。