2016-11-02 4 views
1

Я использую весеннюю безопасность, и я хочу, чтобы начальный объект User в сеансе после успешного входа пользователя в систему.Весна autwireing области области сеанса в AuthenticationSuccessHandler не работает

Конфигурация безопасности, как показано ниже:

@Configuration 
@EnableWebSecurity 
@PropertySource("classpath://configs.properties") 
public class SecurityContextConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private Environment env; 

    @Autowired 
    SimpleUrlAuthenticationSuccessHandler simpleUrlAuthenticationSuccessHandler; 


    @Autowired 
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception { 

     auth.inMemoryAuthentication() 
      .withUser(env.getProperty("security.user1.userid")) 
      .password(env.getProperty("security.user1.pass")) 
      .roles(env.getProperty("security.user1.role")); 
    } 


    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     http.authorizeRequests().antMatchers("/*.cm") 
       .access("hasRole('ADMIN')") 
       .and() 
       .formLogin() 
        .loginPage("/public-page.cm") 
        .loginProcessingUrl("/j_spring_security_check") 
        .usernameParameter("j_username") 
        .passwordParameter("j_password") 
        .successHandler(simpleUrlAuthenticationSuccessHandler) 
        .failureUrl("/public-page-authentication-failure.cm") 
       .and() 
        .logout() 
        .logoutSuccessUrl("/public-page.cm") 
        .invalidateHttpSession(true) 
        .logoutUrl("/j_spring_security_logout") 
       .and() 
        .csrf().disable(); 

    } 

    /** 
    * configure which patterns the spring security should not be applied 
    */ 
    @Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers("/index.jsp", "/public-page.jsp", "/public-page.cm", 
       "/public-page-authentication-failure.cm", "/images/**", "/css/**", "/js/**"); 
    } 

} 

User является

@Component 
@Scope("session") 
public class User { 

    private String selectedSystem; 
    private String selectedBank; 

}

SimpleUrlAuthenticationSuccessHandler является таким, как:

@Component 
public class SimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler { 
    protected Log logger = LogFactory.getLog(this.getClass()); 

    @Autowired 
    private User user; 

Ошибка:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'user': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request. 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:355) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) 

Я добавил RequestContextListener к веб-приложение, как показано ниже:

public class WebAppInitializer implements WebApplicationInitializer { 

    @Override 
    public void onStartup(ServletContext servletContext) throws ServletException { 
     AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext(); 
     appContext.register(DatabaseContextConfig.class); 


     servletContext.addListener(new ContextLoaderListener(appContext)); 
     servletContext.addListener(new RequestContextListener()); 

     //Add Spring security filter 
     FilterRegistration.Dynamic springSecurityFilterChain = servletContext.addFilter(
       AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, DelegatingFilterProxy.class); 
     springSecurityFilterChain.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*"); 

    } 

} 

Я прочитал How to retrieve a session-scoped bean inside AuthenticationSuccessHandler? но это не помогает

Когда я пытаюсь Autowire ни сессионный компонент, он отлично работает.

Любая идея, как это исправить?!

ответ

1

Ваше исключение касается вашего пользовательского компонента, который вы предоставили ему сфера действия. Кажется, что вы пропустили какую-то конфигурацию для области сеанса.

Весной MVC у нас есть дополнительные области, потому что мы работаем с контекстом веб-приложения, дополнительные области: область сеанса, область запроса, область применения.

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

В web.xml вам нужно добавить слушатель, как это:.

<listener> 
     <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 
</listener> 

Этот приемник будет связан с каждым запросом приходит в

Теперь, с бобом, который вам хотят иметь объем сеанса, вам нужно добавить к нему контекстными прокси-сервер, для того, чтобы сделать это вам нужно добавить пространство имен АОП в файл конфигурации, а также:

<bean class="user.package.User" scope="session"> 
    <aop:scoped-proxy/> 
</bean> 

этот боб должен быть на e dispatcher-servlet.xml file

Это все, все готово.

Посмотрите здесь о том, как использовать контекстный-прокси с конфигурацией Java:

Spring JavaConfig of aop:scoped proxy

+0

При запуске сервера я перед этой ошибкой ** Bean с именем «пользователем», как ожидается, будет типа [user.package .User], но на самом деле был тип [com.sun.proxy. $ Proxy36] ** –

+0

Я не имел в виду, что вы на самом деле используете user.package.User, вместо этого вам нужно использовать свой пакет. если ваш пользовательский класс находится в пакете bla.bla.foo затем используйте bla.bla.foo.User –

+0

Конечно, я использовал свой пакет. Похоже, что ошибка связана с установкой режима прокси для 'User' bean –

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