第21章 OAuth2LoginAuthenticationWebFilter 之AuthenticationSuccessHandler

当认证成功后(获取用户信息),会进行认证成功回调。我们可以配置自定义的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版权协议,转载请附上原文出处链接和本声明。