2016-11-22 3 views
1

У меня есть библиотека auth-cas, которая обеспечивает аутентификацию для моего проекта загрузки Spring. В этой библиотеке Auth-Cas есть класс, который расширяет WebSecurityConfigurerAdapter с следующей функцией конфигурированияБезопасность в Spring Boot - несколько WebSecurityConfigurerAdapter

@Override 
@ConditionalOnProperty(value = "ugent.cas.serviceUrl", matchIfMissing = true) 
@ConditionalOnClass(Cas.class) 
protected void configure(HttpSecurity http) throws Exception { 
    http.exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint()); 

    if (basicAuthenticationProviders != null) { 
     http.addFilter(basicAuthFilter()); 
    } 

    http.addFilter(casAuthenticationFilter()) 
      .addFilter(requestSSOLogoutToCASServerLogoutFilter()) 
      .logout() 
      .deleteCookies("JSESSIONID") 
      .permitAll() 
      .logoutSuccessUrl("/logout.html") 
      .and() 
      .csrf() 
      .disable() 
      .headers() 
      .frameOptions() 
      .disable(); 

    http.authorizeRequests() 
      .antMatchers(HttpMethod.OPTIONS, "/api/**").permitAll() 
      .antMatchers("/**").authenticated(); 
} 

Как это должна быть черным ящиком Я добавил мой собственный WebSecurityConfigurerAdapter, который выглядит следующим образом:

@Configuration 
//@Order(Integer.MAX_VALUE) 
//@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
@Order(1) 
public class AuthSecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Override 
    public void configure(WebSecurity webSecurity) throws Exception { 
     webSecurity 
       .ignoring() 
       // All of Spring Security will ignore the requests 
       .antMatchers("/choose.html") 
       .antMatchers("/account/*"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http/*.addFilter(usernamePasswordAuthenticationFilter()) 
       .formLogin() 
       .permitAll() 
       .and() 
       .logout() 
       .deleteCookies("JSESSIONID") 
       .permitAll() 
       .logoutSuccessUrl("/logout.html") 
       .and() 
       .csrf() 
       .disable() 
       .headers() 
       .frameOptions() 
       .disable(); 
      */  

       .authorizeRequests() 
       .anyRequest().authenticated() 
       .and() 
       .authenticationProvider(AuthenticationProvider()) 
       .formLogin() 
       .permitAll() 
       .and() 
       .csrf() 
       .disable() 
       .headers() 
       .frameOptions() 
       .disable() 
       ; 

    } 

    @Bean 
    public AuthenticationProvider AuthenticationProvider() { 
     return new LCAAuthenticationProvider(); 
    } 

    @Bean 
    public UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter() throws Exception{ 
     UsernamePasswordAuthenticationFilter filter = new UsernamePasswordAuthenticationFilter(); 
     filter.setAuthenticationManager(authenticationManager()); 
     return filter; 
    } 
} 

My Custom AuthenticationProvider реализует'AuthenticationProvider 'и работает так же, как на странице перенаправляет меня на страницу/login, и я могу войти с учетными данными в свою пользовательскую базу. Проблема только в том, что я уже вошел в систему с другой сетью auth cas. Я должен быть аутентифицирован, но по-прежнему запрашивает у меня свой собственный поставщик аутентификации.

Как настроить HttpSecurity так, чтобы он работал с моими 2 поставщиками аутентификации.

Другой связанный вопрос, как я могу проигнорировать страницу /choose.html предоставить возможность между входом в систему с одним из двух поставщиков проверки подлинности?

EDIT

Это моя текущая конфигурация'WebSecurityConfigurererAdapter'

@Configuration 
//@Order(Integer.MAX_VALUE) 
//@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
@Order(0) 
public class AuthSecurityConfiguration extends WebSecurityConfigurerAdapter { 

    /** 
    * The authProvider bean used as a cas authentication provider. 
    */ 
    @Autowired 
    private LCAAuthenticationProvider authProvider; 

    @Override 
    public void configure(WebSecurity webSecurity) throws Exception { 
     webSecurity 
       .ignoring() 
       // All of Spring Security will ignore the requests 
       .antMatchers("/choose.html") 
       .antMatchers("/account/*"); 
    } 

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

     /** 
    * The authenticationManagerBean bean. 
    * 
    * @return the authenticationManagerBean 
    * @throws Exception 
    */ 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

    /** 
    * The loginUrlAuthenticationEntryPoint bean 
    * 
    * @return the loginUrlAuthenticationEntryPoint 
    */ 
    @Bean 
    public LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint() { 
     LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint("/choose.html"); 
     //ep.setLoginUrl(cas.getLoginUrl()); 

     return ep; 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.exceptionHandling().authenticationEntryPoint(loginUrlAuthenticationEntryPoint()); 

     http.addFilter(usernamePasswordAuthenticationFilter()) 
       .formLogin() 
       .permitAll() 
       .and() 
       .logout() 
       .deleteCookies("JSESSIONID") 
       .permitAll() 
       .logoutSuccessUrl("/logout.html") 
       .and() 
       .csrf() 
       .disable() 
       .headers() 
       .frameOptions() 
       .disable(); 
      /* 

       .authorizeRequests() 
       .anyRequest().authenticated() 
       .and() 
       .authenticationProvider(AuthenticationProvider()) 
       .formLogin() 
       .loginPage("choose.html") 
       .permitAll() 
       .and() 
       .csrf() 
       .disable() 
       .headers() 
       .frameOptions() 
       .disable() 
       ; 
      */ 
    } 

    @Bean 
    public LCAAuthenticationProvider lcaAuthenticationProvider() { 
     return new LCAAuthenticationProvider(); 
    } 

    @Bean 
    public UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter() throws Exception{ 
     UsernamePasswordAuthenticationFilter filter = new UsernamePasswordAuthenticationFilter(); 
     filter.setAuthenticationManager(authenticationManager()); 
     return filter; 
    } 
} 

Но я получаю следующее сообщение об ошибке:

Exception in thread "main" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException 
     at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:62) 
     at java.lang.Thread.run(Unknown Source) 
Caused by: java.lang.reflect.InvocationTargetException 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 
     at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:54) 
     ... 1 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built 
     at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) 
     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 
     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:296) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) 
     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) 
     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) 
     at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) 
     at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) 
     at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) 
     at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) 
     at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) 
     at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) 
     at be.ugent.lca.Application.main(Application.java:16) 
     ... 6 more 
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built 
     at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) 
     at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) 
     ... 26 more 
Caused by: org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built 
     at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:44) 
     at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:105) 
     at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$699e3cc3.CGLIB$springSecurityFilterChain$2(<generated>) 
     at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$699e3cc3$$FastClassBySpringCGLIB$$e656a0ba.invoke(<generated>) 
     at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) 
     at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:355) 
     at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$699e3cc3.springSecurityFilterChain(<generated>) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 
     at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) 

я могу отслеживать ошибки в линии 44 в https://github.com/spring-projects/spring-security/blob/master/config/src/main/java/org/springframework/security/config/annotation/AbstractSecurityBuilder.java, но я не могу найти причину этого

+0

Любая причина для нисходящего потока? Я был бы рад изменить вопрос, соответствующий предложениям. – turoni

ответ

1

Вам необходимо поместить фильтр авторизации и фильтр имени пользователя в свою собственную конфигурацию (AuthSecurityConfiguration) и сделать его первым, а затем определить точку входа для select.html и фильтр для обработки запроса от choose.html, а затем перенаправить на разные URL-адреса (например,/login или/auth) зависят от выбора. так что это будет, как следующее. (Я сделал что-то подобное раньше, поэтому я просто скопировать их, вы можете изменить свой собственный)

<security:http xmlns="http://www.springframework.org/schema/security" entry-point-ref="clientAuthenticationEntryPoint"> 
     <intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" /> 
     <intercept-url pattern="/choose.html" access="IS_AUTHENTICATED_ANONYMOUSLY" /> 
     <intercept-url pattern="/autherror" access="IS_AUTHENTICATED_ANONYMOUSLY" /> 
     <intercept-url pattern="/**/**" access="IS_AUTHENTICATED_FULLY"/> 
     <custom-filter ref="logoutFilter" position="LOGOUT_FILTER" /> 
     <custom-filter ref="authenticationBrokerProcessingFilter" after="LOGOUT_FILTER" /> 
     <custom-filter ref="oauth2ClientContextFilter" after="EXCEPTION_TRANSLATION_FILTER"/> 
     <custom-filter ref="oAuth2AuthenticationProcessingFilter" before="FILTER_SECURITY_INTERCEPTOR"/> 
     <form-login 
       login-page="/login" 
       default-target-url="/main" 
       username-parameter="username" 
       password-parameter="password" 
       login-processing-url="/loginSubmit" 
       authentication-failure-handler-ref="passwordFailureHandler" 
       authentication-success-handler-ref="passwordAuthenticationSuccessHandler" 
       always-use-default-target="false" 
       /> 
     <csrf /> 
     <access-denied-handler ref="accessDeniedHandler" /> 
    </security:http> 


<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> 
     <constructor-arg name="loginFormUrl" value="/choose.html"/> 
    </bean> 

Как вы можете видеть XML, есть два метода аутентификации, auth2 и пароль пользователя. authenticationBrokerProcessingFilter будет обрабатывать запрос from choose.html;

пароль пользователя пароль будет обрабатывать запрос /loginSubmit от login страница;

фильтр auth2 будет обрабатывать запрос /oauth2-login от sso с кодом.

+0

Я использую весенний ботинок, поэтому я не думаю, что смогу выполнить любую xml-конфигурацию. – turoni

+0

Вы можете изменить эти xml на Java. – chaoluo

+0

Как? Решение на основе аннотаций, которое решает мою проблему, я награду за награду. – turoni

Смежные вопросы