2016-11-17 59 views
0

我已經實現了具有用於登錄/註銷的REST通道的單面應用程序。我已經開始使用JWT,但我想轉向基於會話的通信。我目前是春天的XML配置:由REST服務創建的彈簧安全令牌未保存在會話中

<http pattern="/spring/login" security="none" create-session="always" /> 
<http pattern="/spring/logout" security="none" create-session="never" /> 

<http pattern="/spring/**" entry-point-ref="restAuthenticationEntryPoint" 
    create-session="always"> 
    <csrf disabled="true" /> 
    <custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthenticationFilter" /> 
</http> 

現在,jwtAuthenticationFilter被修改,使得它不記錄如果驗證是否存在,如果不是,它是從頭部解析:

@Override 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
     throws IOException, ServletException { 
    HttpServletRequest req = (HttpServletRequest) request; 
    HttpServletResponse res = (HttpServletResponse) response; 

    // skip if authorization already exists 
    Authentication sessionAuth = SecurityContextHolder.getContext().getAuthentication(); 
    if (sessionAuth != null) { 
     LOGGER.info("Already authenticated as {}", sessionAuth.getPrincipal()); 
     chain.doFilter(request, response); 
     return; 
    } 
    LOGGER.info("Try to authorize"); 

的/春天/ login方法創建令牌,並試圖把它變成安全上下文:

SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS512), claimsSet); 
    try { 
     signedJWT.sign(signer); 
     String token = "Bearer " + signedJWT.serialize(); 
     response.setToken(token); 

     Authentication auth = authenticationManager.authenticate(new JWTToken(signedJWT)); 
     SecurityContextHolder.getContext().setAuthentication(auth);    
    } catch(JOSEException | ParseException e) { 

我期待什麼,是該令牌將出現在接下來的安全上下文REST呼叫。但是,日誌表明,通過下一個請求,令牌不在安全上下文中,它被創建並通過servlet過濾器放到那裏,然後它就會出現在後續請求中。

我在這裏做錯了什麼?我期望,如果我要求在/ spring/login調用上創建會話,Authentication放入SecurityContext也會在會話中保留。這顯然不是這種情況。爲了讓Spring Security保留REST調用中存儲的令牌,我需要做些什麼?

回答

0

由於security="none",Spring安全上下文未保存到會話中。 Spring的安全過濾器並未針對該請求啓動,其中包括將安全上下文保留到會話中的安全過濾器。

的解決方案是爲登錄/註銷提供匿名身份驗證:

<http request-matcher="regex" pattern="/spring/log(in|out)" create-session="ifRequired" entry-point-ref="restAuthenticationEntryPoint" > 
    <csrf disabled="true" /> 
    <custom-filter before="FIRST" ref="anonymousAuthFilter" /> 
</http> 

<beans:bean id="anonymousAuthFilter" 
    class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter"> 
    <beans:constructor-arg value="Anonymous"/> 
</beans:bean> 

我不是很高興通過這種結構,因爲它需要製造假身份驗證,以便能夠創造真實的,但我無法找到更好的東西。