Java 配置中带有自定义身份验证管理器的 Oauth 授权服务器

Oauth authorization server with custom authentication manager in Java config

我在应用程序中有多个身份验证管理器。我用豆名来区分它们。我的 xml 部分与 oauth 授权服务器相关的配置看起来像并且工作正常:

<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />

<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler" >
    <oauth:authorization-code disabled="true" />
    <oauth:implicit disabled="false" />
    <oauth:refresh-token disabled="false" />
    <oauth:client-credentials disabled="false" />
    <oauth:password authentication-manager-ref="authenticationManager" />
</oauth:authorization-server>

<oauth:resource-server id="resourceServerFilter" resource-id="resource-id" token-services-ref="tokenServices" />

<sec:authentication-manager id="clientAuthenticationManager">
    <sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>

<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
      xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    <anonymous enabled="false" />
    <http-basic entry-point-ref="clientAuthenticationEntryPoint" />
    <!-- include this only if you need to authenticate clients via request parameters -->
    <custom-filter ref="oauthClientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

我正在尝试将其移动到基于 Java 的配置(在某些 SecurityConfig class 中),目前为止还不错。我试过类似的东西:

@Configuration
@EnableAuthorizationServer
protected static class OAuth2AuthConfig extends AuthorizationServerConfigurerAdapter {

    @Resource(name = "authenticationManager")
    private AuthenticationManager authenticationManager;

    @Resource
    private OAuth2AuthenticationEntryPoint authenticationEntryPoint;

    @Resource(name = "clientDetails")
    private ClientDetailsService clientDetailsService;

    @Resource
    private TokenStore tokenStore;

    @Resource
    private TokenStoreUserApprovalHandler userApprovalHandler;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.authenticationEntryPoint(authenticationEntryPoint);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userApprovalHandler(userApprovalHandler)
                .tokenStore(tokenStore);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(clientDetailsService);
    }
}

@Configuration
@EnableResourceServer
protected static class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter {

    @Resource
    private DefaultTokenServices tokenServices;

    @Resource(name = "authenticationManager")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId(RESOURCE_ID).tokenServices(tokenServices).authenticationManager(authenticationManager);
    }
}

但是它仍然抱怨多个身份验证管理器,尽管我明确设置了 endpoints.authenticationManager(authenticationManager)

通过一些调试,我可以看到它尝试在 class WebSecurityConfigurerAdapter 中进行配置,并且它在 authenticationManager() 中遇到多个身份验证管理器。我可以覆盖它还是我错过了什么?

  1. AuthorizationServer - 这里有一种方法可以防止 Spring 在
    上失败 org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#authenticationManager 通过简单地覆盖方法 org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerSecurityConfiguration#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder) - explanation
  2. ResourceServer - 遗憾的是没有类似处理相应问题的方法。您能做的最好的事情是将全局身份验证管理器的实例数量减少到一个。