2017-09-04 76 views
0

環境:的Http Session是空的AuthenticatedWebSession檢票和春季安全

<wicket.version>7.7.0</wicket.version> 
<spring.version>4.3.8.RELEASE</spring.version> 
<springsecurity.version>4.2.3.RELEASE</springsecurity.version> 

我有自定義類從AuthenticatedWebSession,如:

public class WicketSession extends AuthenticatedWebSession { 

    private static final Logger log = LoggerFactory.getLogger(WicketSession.class); 

    private static final long serialVersionUID = 1L; 

    private final HttpSession httpSession; 

    @SpringBean(name = "authenticationManager") 
    private AuthenticationManager authenticationManager; 

    public WicketSession(Request request) { 
     super(request); 
     this.httpSession = ((HttpServletRequest) request.getContainerRequest()).getSession(); 
     log.debug("Got httpSession: {}", this.httpSession); 
     Injector.get().inject(this); 
    } 

    @Override 
    public boolean authenticate(String username, String password) { 
     try { 
      final Authentication auth = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); 
      log.debug("Username '{}' is {} auth with authorities: {}", 
        username, auth.isAuthenticated(), auth.getAuthorities()); 
      if (auth.isAuthenticated()) { 
       // the authentication object has to be stored in the SecurityContextHolder and in the HttpSession manually, so that the 
       // security context will be accessible in the next request 
       SecurityContextHolder.getContext().setAuthentication(auth); 
       httpSession.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, 
         SecurityContextHolder.getContext()); 
       return true; 
      } else { 
       return false; 
      } 
     } catch (AuthenticationException e) { 
      log.warn("Failed login attempt due to exception!", e); 
      return false; 
     } 
    } 


} 

春季安全配置,如:

@Configuration 
@EnableWebSecurity 
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { 

    public SpringSecurityConfig() { 
     super(false); 
    } 

    @Override 
    @Bean 
    public UserDetailsService userDetailsService() { 
     final InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); 
     manager.createUser(User.withUsername("admin").password("admin").roles("ADMIN").build()); 
     manager.createUser(User.withUsername("rudi").password("rudi").roles("USER").build()); 
     return manager; 
    } 

    @Bean(name = "authenticationManager") 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.csrf().disable().authorizeRequests() 
       .antMatchers("/").permitAll() 
       .antMatchers("/user/**").authenticated() 
       .antMatchers("/admin/**").hasRole("ADMIN") 
       .antMatchers("/**").permitAll() 
       .and().formLogin().loginPage("/login") 
       .and().addFilter(new SecurityContextPersistenceFilter()).securityContext(); 
    }  
} 

春天應用配置如:

@PropertySource({"classpath:/META-INF/rcommerce.properties"}) 
@Configuration 
@EnableWebMvc 
@EnableTransactionManagement 
@Import({ 
    SpringSecurityConfig.class}) 
public class AppConfig { 

    @Bean 
    public AuthenticatedWebApplication webApp() { 
     return new WicketApplication(); 
    } 

} 

定製類從AbstractSecurityWebApplicationInitializer像:

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { 

    public SecurityWebApplicationInitializer() { 
     super(SpringSecurityConfig.class); 
    } 

} 

的web.xml:

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    version="3.0"> 

    <display-name>rcommerce</display-name> 

    <!-- WICKET FILTER--> 
    <filter> 
     <filter-name>wicket.rcommerce</filter-name> 
     <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class> 
     <init-param> 
      <param-name>applicationFactoryClassName</param-name> 
      <param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value> 
     </init-param> 
     <init-param> 
      <param-name>applicationBean</param-name> 
      <param-value>webApp</param-value> 
     </init-param> 
    </filter> 
    <filter-mapping> 
     <filter-name>wicket.rcommerce</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <!-- MDC FILTER --> 
    <filter> 
     <description>A servlet filter that inserts various values retrieved from the incoming http request into the MDC.</description> 
     <filter-name>MDCInsertingServletFilter</filter-name> 
     <filter-class>ch.qos.logback.classic.helpers.MDCInsertingServletFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>MDCInsertingServletFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <filter> 
     <filter-name>MoreMdcServletFilter</filter-name> 
     <filter-class>com.rudiwijaya.rcommerce.servlet.MoreMdcServletFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>MoreMdcServletFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <!-- SPRING REST SERVLET--> 
    <servlet> 
     <servlet-name>spring-web</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextClass</param-name> 
      <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> 
     </init-param> 
<!--  <init-param> --> 
      <!-- use just the root WebApplicationContext --> 
<!--   <param-name>contextConfigLocation</param-name> --> 
<!--   <param-value>org.soluvas.sanad.app.ServletConfig</param-value> --> 
<!--   <param-value></param-value> --> 
<!--  </init-param> --> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>spring-web</servlet-name> 
     <url-pattern>/*</url-pattern> 
    </servlet-mapping> 
    <!-- SPRING REST FILTER--> 
    <filter> 
     <filter-name>httpPutFormFilter</filter-name> 
     <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>httpPutFormFilter</filter-name> 
     <servlet-name>spring-web</servlet-name> 
    </filter-mapping> 

    <!-- The SpringWebApplicationFactory will need access to a Spring Application 
     context, configured like this... --> 
    <!-- SPRING CONFIG --> 
    <context-param> 
     <param-name>contextClass</param-name> 
     <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> 
    </context-param> 
    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>com.rudiwijaya.rcommerce.AppConfig</param-value> 
    </context-param> 

    <!-- LISTENERS --> 
    <listener> 
     <listener-class>ch.qos.logback.classic.selector.servlet.ContextDetachingSCL</listener-class> 
    </listener> 
    <listener> 
     <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 
    </listener> 

    <!-- ERROR PAGE HANDLING --> 
    <error-page> 
     <error-code>404</error-code> 
     <location>/404.html</location> 
    </error-page> 

    <!-- TIMEOUT --> 
    <session-config> 
     <session-timeout>120</session-timeout> 
    </session-config> 

</web-app> 

當我打電話session.signIn,得到了錯誤,如:

Root cause: 

java.lang.NullPointerException 
    at com.rudiwijaya.rcommerce.WicketSession.authenticate(WicketSession.java:60) 
    at org.apache.wicket.authroles.authentication.AuthenticatedWebSession.signIn(AuthenticatedWebSession.java:66) 
    at com.rudiwijaya.rcommerce.pages.LoginButton.doAuthenticate(LoginButton.java:132) 
    at com.rudiwijaya.rcommerce.pages.LoginButton.onSubmit(LoginButton.java:165) 
    at org.apache.wicket.ajax.markup.html.form.AjaxButton$1.onSubmit(AjaxButton.java:113) 
    at org.apache.wicket.ajax.form.AjaxFormSubmitBehavior$AjaxFormSubmitter.onSubmit(AjaxFormSubmitBehavior.java:215) 
    at org.apache.wicket.markup.html.form.Form.delegateSubmit(Form.java:1307) 
    at org.apache.wicket.markup.html.form.Form.process(Form.java:976) 
    at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:797) 
    at org.apache.wicket.ajax.form.AjaxFormSubmitBehavior.onEvent(AjaxFormSubmitBehavior.java:171) 
    at org.apache.wicket.ajax.AjaxEventBehavior.respond(AjaxEventBehavior.java:155) 
    at org.apache.wicket.ajax.AbstractDefaultAjaxBehavior.onRequest(AbstractDefaultAjaxBehavior.java:601) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.apache.wicket.RequestListenerInterface.internalInvoke(RequestListenerInterface.java:258) 
    at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:241) 
    at org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler.invokeListener(ListenerInterfaceRequestHandler.java:248) 
    at org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler.respond(ListenerInterfaceRequestHandler.java:234) 
    at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:895) 
    at org.apache.wicket.request.RequestHandlerStack.execute(RequestHandlerStack.java:64) 

錯誤(它是httpSession爲null):

httpSession.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, 
         SecurityContextHolder.getContext()); 

我該怎麼辦?

+0

'httpSession'爲空會話可能已過期。 – soorapadman

+0

AUthenticatedAplication,newSession()','getWebSessionClass()'方法的類可以包含在這裏嗎? –

回答

1

你有多個web容器節點嗎?使用會話複製?

作爲一般規則,你不應該保持對Http Session的硬引用。特別是在Wicket應用程序!因爲如果WicketSession被序列化,然後反序列化這個成員字段將是null

無論何時需要它時,都可以更好地查找HttpSession,即在方法中提取((HttpServletRequest) request.getContainerRequest()).getSession();,並在需要方法體內的會話時調用它。

+0

謝謝@ martin-g,我會嘗試你的建議。並沒有會話複製,只有兩場戰爭在單個tomcat ... –

+0

如果我在https://cwiki.apache.org/confluence/display/WICKET/Spring+Security+and+Wicket-auth-roles中讀取,有沒有'''MyAuthenticatedWebSession'''中的httpSession,可以嗎?因爲在另一個例子像https://github.com/dmbeer/wicket-7-spring-security/blob/master/src/main/java/com/copperarrow/auth/SecureWebSession.java或https://github.com /thombergs/wicket-spring-security-example/blob/master/src/main/java/org/wickedsource/SecureWebSession.java,有httpSession。 –

+0

我刪除了httpSession和行: '''httpSession.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,SecurityContextHolder.getContext());''',是否可以作爲概念Spring Security&Wicket? –