2016-11-02 75 views
1

我正在使用spring安全性,並且想在用戶成功登錄後在會話中初始化對象User在AuthenticationSuccessHandler中自動調用會話作用域bean的Spring不起作用

安全配置是如下:

@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到下面的Web應用程序:

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無會話bean,它工作正常。

任何想法如何解決它?

回答

1

你的異常是關於你給它的用戶bean的一個會話範圍。看起來你錯過了會話​​範圍的一些配置。

在Spring MVC中,我們有額外的範圍,因爲我們正在使用Web應用程序上下文,其他範圍是:會話範圍,請求範圍,應用程序範圍。

我通常使用XML配置,所以我的答案將採用這種格式,之後您可以對java配置進行翻譯。

在web.xml中你將需要添加一個監聽器,這樣的:

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

此偵聽器將與每個請求相關進來

現在,你豆你希望有一個會話範圍,你需要給它添加一個範圍代理,爲了做到這一點,你需要給AOP命名空間添加到您的配置文件,並且:

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

這個bean應該待上e dispatcher-servlet.xml文件

就是這樣,你全部設置好了。

看這裏如何使用範圍的代理與Java的配置:

Spring JavaConfig of aop:scoped proxy

+0

在服務器啓動期間我面對這個錯誤**豆命名爲「用戶」有望成爲類型[user.package .User]但實際上是[com.sun.proxy。$ Proxy36]類型** –

+0

我並不是說你實際使用user.package.User,而是需要使用你的包。如果你的用戶類在bla.bla包中。foo然後使用bla.bla.foo.User –

+0

當然,我已經使用我的包。看來這個錯誤是因爲爲'User' bean設置了一個代理模式 –

相關問題