8

Spring Security Reference section 5.7에 따르면 둘 이상의 보안 어댑터를 정의 할 수 있어야합니다.다른 인증 프로 바이더 (Web App 용 API 및 LDAP의 기본 인증)와 함께 여러 WebSecurityConfigurerAdapter 사용

나는 똑같이하려고하지만 성공하지는 못합니다. 서버를 재부팅 한 후 기본 인증을 사용하면 API가 정상적으로 작동하지만 x 두 번 로그인하면 (양식) 페이지로 리디렉션됩니다. API 호출이 아닌 웹 애플리케이션에서만 발생합니다.

내 코드 :

@EnableWebSecurity 
public class MultiHttpSecurityConfig { 

    @Configuration 
    @Order(1) 
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { 

     @Autowired 
     private Environment env; 

     @Autowired 
     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
      auth.inMemoryAuthentication(). 
       withUser("admin").password("pw_test").roles(API_ROLE); 
     } 

     protected void configure(HttpSecurity http) throws Exception { 
      http 
       .antMatcher("/services/**") 
       .authorizeRequests() 
       .anyRequest().hasRole(API_ROLE) 
       .and() 
       .httpBasic() 
       .and() 
       .csrf() 
       .disable(); 
     } 
    } 

    @Configuration 
    @Order(2) 
    public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { 

     @Autowired 
     private Environment env; 

     @Autowired 
     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
      auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider()); 
      auth.eraseCredentials(false); 
     } 

     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      // LDAP FORM AUTHENTICATION 
      http.authorizeRequests() 
       .antMatchers("/login.html").permitAll() 
       .antMatchers("/css/**").permitAll() 
       .antMatchers("/js/**").permitAll() 
       .antMatchers("/images/**").permitAll() 
       .anyRequest().authenticated() 
      .and().formLogin() 
       .failureUrl("/login.html?error=1") 
       .loginPage("/login.html") 
       .loginProcessingUrl("/j_spring_security_check") 
       .defaultSuccessUrl("/success.html") 
       .usernameParameter("j_username") 
       .passwordParameter("j_password") 
       .permitAll(); 

      http.csrf().disable(); 

      // iFRAMES SETTINGS 
      http 
       .headers() 
       .frameOptions().sameOrigin() 
       .httpStrictTransportSecurity().disable(); 

      // HTTPS 
      http 
       .requiresChannel() 
       .anyRequest() 
       .requiresSecure(); 

      //MAP 8080 to HTTPS PORT 
      http.portMapper().http(8080).mapsTo(443); 
     } 

     @Bean 
     public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() { 
      CustomLdapAuthenticationProvider provider = new CustomLdapAuthenticationProvider(env.getProperty("ldap.domain"), env.getProperty("ldap.url"), env.getProperty("ldap.base")); 
      provider.setConvertSubErrorCodesToExceptions(true); 
      provider.setUseAuthenticationRequestCredentials(true); 
      return provider; 
     } 
    } 
} 

어떤 생각?

스프링 부트 버전 1.4.1-RELEASE와 스프링 보안 버전 4.1.3-RELEASE를 사용하고 있습니다.

+0

아래 답변 작업을 했습니까? – theLearner

+0

네, 잘 작동합니다! – Dimi

답변

2

동일한 AuthenticationManagerBuilder을 autowire 때문에 두 구성에 모두 동일한 AuthenticationManager을 사용합니다.

Spring Security Architecture를 참조하십시오

@Configuration 
public class ApplicationSecurity extends WebSecurityConfigurerAdapter { 

    ... // web stuff here 

    @Autowired 
    public initialize(AuthenticationManagerBuilder builder, DataSource dataSource) { 
     auth.jdbcAuthentication().dataSource(dataSource).withUser("dave") 
      .password("secret").roles("USER"); 
    } 

} 

이 예제는 웹 응용 프로그램에 관한 것으로,하지만 AuthenticationManagerBuilder의 사용은 (웹 애플리케이션 보안이 구현되는 방법에 대한보다 자세한 사항은 아래 참조)보다 광범위하게 적용 할 수있다. AuthenticationManagerBuilder@Bean에있는 메소드에 @Autowired입니다. 이것이 글로벌 (상위) AuthenticationManager를 빌드하게합니다. 반면에 우리는이 방법을 수행 한 경우 :

다음 AuthenticationManagerBuilder은 세계 하나의 자식 인 AuthenticationManager "로컬"을 구축하는 데 사용됩니다 (설정자의 방법의 @Override 사용)
@Configuration 
public class ApplicationSecurity extends WebSecurityConfigurerAdapter { 

    @Autowired 
    DataSource dataSource; 

    ... // web stuff here 

    @Override 
    public configure(AuthenticationManagerBuilder builder) { 
     auth.jdbcAuthentication().dataSource(dataSource).withUser("dave") 
      .password("secret").roles("USER"); 
    } 

} 

.