具有自定义AuthenticationManager的SpringSecurity BasicAuthenticationFilter

时间:2018-11-30 16:56:28

标签: java spring spring-security oauth spring-security-oauth2

对于BasicAuthenticationFilter,我试图注入自己的AuthenticationManager。 但是,当我调试启动程序时,我总是发现 BasicAuthenticationFilter.java 类没有使用我的AuthenticationManager。

如何将其传递给BasicAuthenticationFilter?

我正在使用SpringBoot 2.1.0和Spring-Security-Oauth2 2.0.1

AuthorizationConfiguration.java

@Configuration
@EnableAuthorizationServer
public class AuthorizationConfiguration extends 
AuthorizationServerConfigurerAdapter {

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
@Qualifier("passwordEncoder")
private PasswordEncoder passwordEncoder;

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    System.out.println(passwordEncoder.encode("SECRET"));
    clients
    .inMemory()
    .withClient("clientapp")
    .authorizedGrantTypes("client_credentials")
    .authorities("USER")
    .scopes("read", "write")
    .secret(passwordEncoder.encode("SECRET"));

}

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

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

WebSecurityConfiguration.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter{

@Override
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Primary
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManager();
}


@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(16); 
}

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring()
    .antMatchers(ResourceConfiguration.TEST_PATHS);
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    DaoAuthenticationProvider daoAuth = new DaoAuthenticationProvider();
    daoAuth.setPasswordEncoder(passwordEncoder());
    auth.authenticationProvider(daoAuth);
}

谢谢您的帮助。

3 个答案:

答案 0 :(得分:0)

在您的WebSecurityConfiguration中,authenticationManagerBean()应该返回您自己的AuthenticationManager bean实例,而不是super.authenticationManager()吗?

答案 1 :(得分:0)

使用给定的配置,您实际上将获得两个BasicAuthenticationFilter的实例。两者都应该使您的AuthenticationManager正常。但是,对于其中一个,它是父级AuthenticationManager,这意味着您还应该在调试器中检查authenticationManager.parent属性。

尽管如此,您的AuthenticationManager可能有几个问题。

Spring Security OAuth将创建两个过滤器链(以及随后的两个BasicAuthenticationFilter,两个AuthenticationManager);一个用于OAuth端点,例如/oauth/token,另一个用于其他所有内容。

为OAuth端点创建的过滤器链采用通过UserDetailsService指定的ClientDetailsServiceConfigurer并将其应用于您指定的AuthenticationManager

如果我采用您的配置并将其放入我的IDE中,然后执行以下操作:

curl --user clientapp:SECRET localhost:8080/oauth/token -dgrant_type=client_credentials

然后它会带着令牌返回。

但是,对于其余请求,它不会将这些客户端应用于AuthenticationManager。这样做的原因是,对于授权服务器,通常有两种不同类型的用户:客户端和最终用户。客户端需要使用OAuth API,而用户只需要使用Web应用程序(登录等)。

这意味着如果您尝试做:

curl --user clientapp:SECRET localhost:8080

它不起作用。用户集尚未应用于该过滤器链。

如果您具有非OAuth2端点,则需要自己在UserDetailsService中指定一组用户。没有这个,当您尝试使用basic击中这些端点时,没有用户可以查找它。

此外,默认的AuthenticationManager将自动提取您的PasswordEncoder。因此,您可以执行以下操作来代替您的WebSecurityConfiguration#configure方法:

@Bean
public UserDetailsService userDetailsService() {
    return new InMemoryUserDetailsService(User
        .withUsername("user")
        .password(passwordEncoder().encode("password"))
        .role("USER")
        .build());
}

(如果您需要做更复杂的事情,也可以自定义AuthenticationManager。)

尝试使用已发布的应用程序(再次将configure中的WebSecurityConfiguration方法更改为上述方法),我也可以这样做:

curl --user user:password localhost:8080

答案 2 :(得分:0)

问题是我在build.gradle中使用了错误的软件包

为解决此问题,我添加了以下软件包:

build.gradle

implementation("org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:${springBootVersion}")
相关问题