簡體   English   中英

Spring 與多個提供商的安全性

[英]Spring security with multiple providers

我正在設置一個有 2 個不同用戶的應用程序:

  • 我的 ldap 中的一個可以與 cas 身份驗證連接
  • 一個外部硬編碼,帶有一個簡單的 formlogin

我創建了 2 個安全配置:

外部用戶配置:

@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配置:

@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;
}

每個配置單獨工作時都有效,但同時存在時,外部配置不起作用。

似乎 CasAuthenticationProvider bean 阻止了 formLogin 工作,我最終進入了 FailureHandler。

這是錯誤:

org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken

我怎樣才能使這兩個配置一起工作?

當您將某些內容標記為@Bean時,您就是將其放入了 spring 可以在需要時將其注入到類中的 bean 池中。

你已經注冊

@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
    ...
}

作為一個@Bean ,它是一個AuthenticationProvider 當您使用@Bean注冊它時,需要它的每個人都會選擇它,這意味着您的WebSecurityConfigurerAdapter都將使用它。

Spring 無法知道您只希望這是在您的一個安全配置中,而不是另一個。

您必須通過刪除@Bean並手動設置它來明確定義您想要它而不是另一個。

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

public CasAuthenticationProvider casAuthenticationProvider() {
    ...
}

您必須始終決定是否要手動設置某些內容,或者使用@Bean並讓 spring 為您注入它。

因此,例如,您正在注冊一個過濾器 (casLogoutFilter) 手動設置它,但也將其定義為@Bean告訴 spring 將其注入過濾器鏈,這有點沒有意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM