Spring Security Spring授权服务器对每个客户端进行身份验证

pbossiut  于 2023-02-04  发布在  Spring
关注(0)|答案(1)|浏览(179)

我正在尝试使用Spring授权服务器构建一个身份提供程序,第三方应用程序将使用它来进行FIM(联合身份管理)。
我们希望每个OAuth客户端都需要身份验证(如果用户尝试使用不同的客户端登录,则需要对每个客户端进行身份验证)。
开箱即用的流程如下所示:

所以有两个问题。

  1. /oauth2/authorize端点只检查会话主体是否经过身份验证,它不关心或不知道主体是针对哪个客户端的。
    1.只有一个/login端点,因此在身份验证期间它不知道使用了哪个客户端。
    我的最佳选择是:
    1.使oauth2/authorize端点重定向到/login时包含查询参数client_id
    1.创建一个自定义AuthenticationFilter,同时将client_id添加到User主体
    1.覆盖oauth2/authorize端点的authorizationRequestConverter,并验证请求中的客户端是否与存储在经过身份验证的主体上的客户端相同
    我错过了什么吗?有人知道更简单的方法吗?
xxb16uws

xxb16uws1#

根据您的上一条评论,似乎有一种可能性是每次都简单地要求身份验证,或者至少每次请求授权时都要求身份验证。在这种情况下,您可以在向客户端发出授权码后使用Filter清除身份验证。这似乎并不理想,而且会导致糟糕的用户体验,但可能会达到您的要求。

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    @Order(1)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
            throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
        // ...

        // Add filter to remove the SecurityContext after successful authorization
        http.addFilterAfter(new RemoveSecurityContextOnAuthorizationFilter(), LogoutFilter.class);

        return http.build();
    }

    private static final class RemoveSecurityContextOnAuthorizationFilter extends OncePerRequestFilter {

        private SecurityContextHolderStrategy securityContextHolderStrategy =
                SecurityContextHolder.getContextHolderStrategy();

        private final LogoutHandler logoutHandler = new CompositeLogoutHandler(
                new CookieClearingLogoutHandler("JSESSIONID"),
                new SecurityContextLogoutHandler()
        );

        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            try {
                filterChain.doFilter(request, response);
            } finally {
                String locationHeader = response.getHeader(HttpHeaders.LOCATION);
                if (locationHeader != null) {
                    UriComponents uriComponents = UriComponentsBuilder.fromUriString(locationHeader).build();
                    if (uriComponents.getQueryParams().containsKey("code")) {
                        Authentication authentication = this.securityContextHolderStrategy.getContext().getAuthentication();
                        this.logoutHandler.logout(request, response, authentication);
                    }
                }

            }
        }

    }

    // ...

}

相关问题