对于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);
}
谢谢您的帮助。
答案 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}")