Spring OAuth2安全性 - 客户端凭据 - 自定义身份验证提供者

问题描述 投票:0回答:1

我在我们的服务架构中编写了一个身份验证服务,它基本上是Spring OAuth2 Authorization Server的一个实现。由此我需要针对许多不同的源对提供的凭证进行身份验证,以支持旧环境。

我主要专注于使用客户端凭据流,其中用户(其他服务)将使用他们自己的凭据来获取令牌,并且暂时不需要OAuth2的授权或刷新。

我已经成功地启动了受Spring Security(@EnableWebSecurity)保护的Spring Boot应用程序。我还成功设置了授权服务器(@EnableAuthorizationServer),它提供必要的端点(/oauth/token)来提供令牌。我已经能够在内存和自定义ClientDetailsS​​ervice中配置Authorization Server以成功获取令牌。这只是为了向自己证明我可以得到一些有用的东西。

我的问题是我需要根据自定义源验证凭据。我没有直接访问密码,当然也不知道它们是如何编码的。

在深入挖掘Spring代码后,我可以通过DaoAuthenticationProvider看到它,通过调用PasswordEncoder.matches()来完成身份验证。不幸的是,我没有从ClientDetailsService获得密码,如果我这样做,也不知道密码是如何编码的,所以自定义PasswordEncoder对我没有多大帮助(同样我需要以多种方式匹配只有一个PasswordEncoder)。所以,我只剩下定义自己的AuthenticationProvider(或AuthenticationManager)。

我能够实现自己的AuthenticationProvider并将其提供给Spring Security配置。这非常有效,我能够将身份验证推迟到我自己的提供程序,该提供程序可以执行我认为合适的任何操作(例如委托给另一个服务进行身份验证),但这仅适用于非OAuth2端点。

现在,这就是一切都开始崩溃的地方。无论出于何种原因,我无法让/oauth/token端点使用我提供的定义的AuthenticationManagerAuthenticationProviders。它始终默认为AuthenticationMangerAnonymousAuthenticationProviderDaoAuthenticationProvider

WebSecurity

这里没什么好玩的。我正在全局公开身份验证管理器,试图在OAuth2配置中注册它。我已经留下了一些注释代码来展示我尝试过的其他一些东西,但它们几乎都完成了同样的事情:它可以处理除OAuth2端点之外的所有内容。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public AuthenticationProvider customAuthenticationProvider;

    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
//      return new ProviderManager(Arrays.asList(customAuthenticationProvider));
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest()
            .authenticated()
        .and()
            .httpBasic();
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .authenticationProvider(customAuthenticationProvider);
    }

//   @Autowired
//   public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//       auth.authenticationProvider(customAuthenticationProvider);
//   }
}

AuthServer

我已经把它剥离到我认为应该是正确的配置。我有意地遗漏了ClientDetailsService,因为它是提供程序配置的一部分,并且它正常工作。我忽略了TokenStore并使用默认值,直到我可以获得身份验证。再次,这里的authenticationManager应该是从WebSecurity暴露的全球性的。我也尝试在端点配置器中创建一个新的ProviderManager,但这对我也不起作用。

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {        
        oauthServer
            .tokenKeyAccess("permitAll()")
            .checkTokenAccess("permitAll()")
        ;
    }

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

我也尝试过扩展AuthorizationServerSecurityConfiguration而没有成功:

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig2 extends AuthorizationServerSecurityConfiguration {

    @Autowired
    public AuthenticationProvider customAuthenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customAuthenticationProvider);
    }
}

我希望我的自定义AuthenticationProvider会显示在列表中,但它不会与我尝试过的一切。

这可能是故意的,但如果是这样的话,提供自定义身份验证方案的正确方法是什么?

我真的想避免它,但我真的需要实现自定义过滤器并绕过Spring提供的所有好东西吗?如果是的话,我该怎么做呢?

java spring authentication spring-security spring-security-oauth2
1个回答
0
投票

我最终为令牌端点配置了额外的BasicAuthenticationFilter。对我来说,这有点乱,因为现在安全过滤器链中有两个相同的过滤器,但它可以解决问题。

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private UserService userService;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer
            .tokenKeyAccess("isAuthenticated()")
            .checkTokenAccess("isAuthenticated()");

        // override the default basic authentication filter in order to provide
        // a custom authentication manager
        oauthServer.addTokenEndpointAuthenticationFilter(new BasicAuthenticationFilter(authenticationManager, new BasicAuthenticationEntryPoint()));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.