首页 文章

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

提问于
浏览
9

上下文

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

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

  • Spring Boot

  • Spring Security OAuth2

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

问题

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

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

以下似乎在 AuthenticationManagerparent 引用中正确注册,但未在运行时委托(由于 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;
      }

    });
  }

}

似乎无论我尝试什么(参见下面的参考资料)当 BasicAuthenticationFilter 在其 doFilter 方法中调用 Authentication authResult = authenticationManager.authenticate(authRequest) 时,我总是在 ProviderManager 中获得以下两个提供者:

[ org.springframework.security.authentication.AnonymousAuthenticationProvider@366815e4, org.springframework.security.authentication.dao.DaoAuthenticationProvider@5da3e311 ]

我相信这可能是 AuthorizationServerSecurityConfigurerclientCredentialsTokenEndpointFilter 方法的结果 . 但是,此类标记为 final ,因此无法自定义 .

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

资源

我尝试/研究过的事情:

2 回答

  • 4

    如果我理解正确,您需要为密码授予中的用户提供自定义身份验证管理器 . 有一个构建器方法: 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) .

  • 0

    正如评论中所提到的,对于以下代码片段来自动装配“全局”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;
                }
    
            };
        }
    }
    

相关问题