[英]Spring security with multiple providers
I am setting up an app with 2 differents users:我正在设置一个有 2 个不同用户的应用程序:
I created 2 Security configurations:我创建了 2 个安全配置:
External User Configuration:外部用户配置:
@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
@Order(1)
public class SecurityVanuatuConfiguration extends WebSecurityConfigurerAdapter {
@Bean
@Override
public UserDetailsService userDetailsService() {
UserDetails user =
User.withUsername("user")
.password("{noop}user")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable().antMatcher("/user/**")
.authorizeRequests()
.requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage(LOGIN_URL).permitAll()
.loginProcessingUrl(LOGIN_PROCESSING_URL)
.failureUrl(LOGIN_FAILURE_URL)
.successHandler(successHandler)
.failureHandler(successHandler)
.and().logout().logoutSuccessUrl(LOGOUT_SUCCESS_URL);
}
Cas Configuration: Cas配置:
@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
@Order(2)
public class SecurityCasConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().antMatcher("/admin/**")
.authorizeRequests()
.requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint())
.and()
.addFilter(casAuthenticationFilter())
.addFilterBefore(casLogoutFilter(), CasAuthenticationFilter.class);
}
@Bean
public SingleSignOutFilter casLogoutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
return singleSignOutFilter;
}
// if I remove this bean, external configuration works
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider provider = new CasAuthenticationProvider();
provider.setServiceProperties(serviceProperties());
provider.setTicketValidator(new Cas30ServiceTicketValidator("https://sso.unc.nc/cas"));
provider.setKey("cas");
provider.setAuthenticationUserDetailsService(successHandler);
return provider;
}
Each configuration work when it's alone, but when there is both, the external doesn't work.每个配置单独工作时都有效,但同时存在时,外部配置不起作用。
It seems that the CasAuthenticationProvider bean prevent the formLogin to work and I endup in the FailureHandler.似乎 CasAuthenticationProvider bean 阻止了 formLogin 工作,我最终进入了 FailureHandler。
Here is the error:这是错误:
org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken
How can I make these 2 configuration work together?我怎样才能使这两个配置一起工作?
when you mark something as @Bean
you are putting it in the pool of beans that spring can use to inject into classes if they need it.当您将某些内容标记为
@Bean
时,您就是将其放入了 spring 可以在需要时将其注入到类中的 bean 池中。
you have registered你已经注册
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
...
}
as a @Bean
which is an AuthenticationProvider
.作为一个
@Bean
,它是一个AuthenticationProvider
。 When you register this using @Bean
it will get picked up by everyone that needs it, meaning that both your WebSecurityConfigurerAdapter
will use it.当您使用
@Bean
注册它时,需要它的每个人都会选择它,这意味着您的WebSecurityConfigurerAdapter
都将使用它。
Spring has no way of knowing that you only want this is in one of your security configurations and not the other. Spring 无法知道您只希望这是在您的一个安全配置中,而不是另一个。
you have to explicitly define that you want it in one and not the other by removing @Bean
and setting it manually.您必须通过删除
@Bean
并手动设置它来明确定义您想要它而不是另一个。
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(casAuthenticationProvider());
}
public CasAuthenticationProvider casAuthenticationProvider() {
...
}
You have to always decied if you want to set something manually, or use @Bean
and let spring inject it for you.您必须始终决定是否要手动设置某些内容,或者使用
@Bean
并让 spring 为您注入它。
So for instance, you are registering a filter (casLogoutFilter) setting it manually but also defining it as @Bean
telling spring to inject it into the filter chain, which sort of doesn't make sense.因此,例如,您正在注册一个过滤器 (casLogoutFilter) 手动设置它,但也将其定义为
@Bean
告诉 spring 将其注入过滤器链,这有点没有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.