简体   繁体   English

Spring 与多个提供商的安全性

[英]Spring security with multiple providers

I am setting up an app with 2 differents users:我正在设置一个有 2 个不同用户的应用程序:

  • one from my ldap that can connect with cas authentication我的 ldap 中的一个可以与 cas 身份验证连接
  • one external, hard coded with a simple formlogin一个外部硬编码,带有一个简单的 formlogin

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.

相关问题 具有多个身份验证提供程序的Spring安全性-UsernameNotFoundException - Spring security with multiple authentication providers - UsernameNotFoundException Spring Security-多个身份验证提供者 - Spring Security - multiple authentication-providers Spring Security的许多提供商 - Spring Security many providers Spring安全 - 使用多个身份验证提供程序进行身份验证 - Spring security - remember-me authentication with multiple authentication providers Spring Security-如何使用Java Config配置多个身份验证提供程序 - Spring security - How to configure multiple authentication providers using java config 多个身份验证提供程序:/ j_spring_security_check和社交登录 - Multiple authentication providers: /j_spring_security_check and social login 了解Spring Security中的身份验证提供程序 - Understanding authentication providers in Spring security Spring Boot / Spring Security根据路径在多个身份验证提供程序之间进行选择 - Spring Boot/Spring Security Choose Between Multiple Authentication Providers Based On Path 同一事务Spring中的多个资源提供者 - Multiple resource providers in same transaction Spring Spring Boot Auth服务器中的多个SSO提供程序 - Multiple SSO providers in Spring Boot Auth server
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM