10

语境

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

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

  • 弹簧靴
  • 春季安全 OAuth2

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

问题

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

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

以下似乎在 的parent引用中正确注册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方法的结果。但是,此类已标记final,因此无法自定义。

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

资源

我尝试过/研究过的事情:

4

2 回答 2

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)。

于 2014-09-15T14:17:34.847 回答
1

正如评论中所提到的,对于自动装配“全局”AuthenticationManager 的以下代码段,您必须以某种方式让上下文知道它。

片段:

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

仅配置 HttpSecurity 的特定实例。

我个人更喜欢将 bean 设置为主要配置,并将我的中央配置的顺序设置为 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;
            }

        };
    }
}
于 2018-04-01T04:27:18.640 回答