如何使用Spring Security OAuth2在Spring Boot中注册自定义BasicAuthenticationFilter AuthenticationProvider

时间:2014-09-04 14:34:10

标签: spring-security basic-authentication spring-boot spring-security-oauth2

上下文

我正在开发一个应用程序,允许经过身份验证的用户创建OAuth2 bearer tokens,以便与组织发布的API一起使用。这个想法是允许用户自己生成/撤销这样的令牌,类似于GitHub的Personal API tokens。然后,用户可以使用发布的令牌获得对受保护资源的编程访问。在此配置中,OAuth"客户端","授权服务器"和资源服务器"属于该组织。目前,所有这些服务都在同一个流程中。

为此,我尝试支持Resource Owner Password Credentials Grant类型。实施环境包括以下内容:

  • Spring Boot
  • Spring Security OAuth2

实现的一个约束是无法访问存储的密码。此处理委托给执行实际身份验证的内部Web服务。

问题

由于无法访问存储密码的限制,因此无法使用默认配置的DaoAuthenticationProvider,因为它需要访问由提供商返回的UserDetails对象提供的密码。 s UserDetailsService

我的猜测是我需要用自定义实现替换这个AuthenticationProvider。但是,所有这样做的尝试似乎都没有生效。

以下似乎在parent的{​​{1}}引用中正确注册,但未在运行时委托(由于AuthenticationManager优先):

DaoAuthenticationProvider

似乎无论我尝试什么(请参阅下面的参考资料)@Configuration public class SecurityConfig extends GlobalAuthenticationConfigurerAdapter { @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(new AuthenticationProvider() { @Override public boolean supports(Class<?> authentication) { // For testing this is easier, but should check for UsernamePasswordAuthentication.class return true; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // Perform custom logic... return authentication; } }); } } 在其ProviderManager方法中调用BasicAuthenticationFilter时,Authentication authResult = authenticationManager.authenticate(authRequest)始终会获得以下两个提供商:

doFilter

我认为这可能是[ org.springframework.security.authentication.AnonymousAuthenticationProvider@366815e4, org.springframework.security.authentication.dao.DaoAuthenticationProvider@5da3e311 ] AuthorizationServerSecurityConfigurer方法的结果。但是,此类标记为clientCredentialsTokenEndpointFilter,因此无法自定义。

任何建议或指示都将不胜感激。

资源

我尝试/研究过的事情:

2 个答案:

答案 0 :(得分:5)

如果我理解正确,您需要为密码授予中的用户提供自定义身份验证管理器。有一个构建器方法:AuthorizationServerEndpointsConfigurer.authenticationManager(AuthenticationManager)。以及使用它的一个例子:

@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

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

    ...

(来自https://github.com/spring-projects/spring-security-oauth/blob/master/tests/annotation/vanilla/src/main/java/demo/Application.java#L42)。

答案 1 :(得分:1)

正如评论中所提到的,以下代码片段可以自动发送“全局&#39;您必须在AuthenticationManager中以某种方式知道上下文。

摘录:

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

仅配置HttpSecurity的特定实例。

我个人更喜欢将bean设置为primary并将中央配置的顺序设置为1以强制此配置优先于其他(自动)配置。

@Order(1)
@Configuration
public class SecurityConfig extends GlobalAuthenticationConfigurerAdapter {

    @Bean
    @Primary
    public AuthenticationProvider authenticationProvider() {
        return new AuthenticationProvider() {

            @Override
            public boolean supports(Class<?> authentication) {
                // For testing this is easier, but should check for
                // UsernamePasswordAuthentication.class
                return true;
            }

            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                // Perform custom logic...
                return authentication;
            }

        };
    }
}