当认证成功后(获取用户信息),会进行认证成功回调。我们可以配置自定义的Handler来处理认证成功后业务代码。
初始化AuthenticationSuccessHandler
在 ServerHttpSecurity 类的内部类 OAuth2LoginSpec 的 configure() 方法内,OAuth2LoginAuthenticationWebFilter 初始化了 AuthenticationSuccessHandler。如果我们没有指定 AuthenticationSuccessHandler,就创建默认的;否则使用指定的。大概创建流程如下源码所示。
private ServerAuthenticationSuccessHandler getAuthenticationSuccessHandler(ServerHttpSecurity http) {
if (this.authenticationSuccessHandler == null) {
RedirectServerAuthenticationSuccessHandler handler = new RedirectServerAuthenticationSuccessHandler();
handler.setRequestCache(http.requestCache.requestCache);
this.authenticationSuccessHandler = handler;
}
return this.authenticationSuccessHandler;
}
OAuth2LoginAuthenticationWebFilter认证成功回调
OAuth2LoginAuthenticationWebFilter处理认证成功回调做哪些事呢?大致分为一下几点:
- 创建 OAuth2AuthorizedClient 对象,并缓存。
- 创建 Authentication 对象(实际是子类 OAuth2AuthenticationToken)
- 调用父类的 onAuthenticationSuccess 方法,并调用 AuthenticationSuccessHandler 的回调方法。
// 子类方法
protected Mono<Void> onAuthenticationSuccess(Authentication authentication, WebFilterExchange webFilterExchange) {
OAuth2LoginAuthenticationToken authenticationResult = (OAuth2LoginAuthenticationToken) authentication;
// 创建 authorizedClient, 是为了缓存
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
authenticationResult.getClientRegistration(), authenticationResult.getName(),
authenticationResult.getAccessToken(), authenticationResult.getRefreshToken());
// 创建 Authentication 的子类, 传递给 AuthenticationSuccessHandler
OAuth2AuthenticationToken result = new OAuth2AuthenticationToken(authenticationResult.getPrincipal(),
authenticationResult.getAuthorities(),
authenticationResult.getClientRegistration().getRegistrationId());
// 缓存 authorizedClient, 并调用父类的方法
return this.authorizedClientRepository
.saveAuthorizedClient(authorizedClient, authenticationResult, webFilterExchange.getExchange())
.then(super.onAuthenticationSuccess(result, webFilterExchange));
// @formatter:on
}
// 父类方法
protected Mono<Void> onAuthenticationSuccess(Authentication authentication, WebFilterExchange webFilterExchange) {
ServerWebExchange exchange = webFilterExchange.getExchange();
SecurityContextImpl securityContext = new SecurityContextImpl();
securityContext.setAuthentication(authentication);
return this.securityContextRepository.save(exchange, securityContext)
// 调用 authenticationSuccessHandler 的回调方法
.then(this.authenticationSuccessHandler.onAuthenticationSuccess(webFilterExchange, authentication))
.subscriberContext(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(securityContext)));
}
版权声明:本文为buffeer原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。