2012-06-27 51 views
1

我一直在研究spring安全性,並且一切正常。但我只是去調試它是如何工作的。所有過濾器都通過http命名空間爲springsecurityfilterchain配置。其中之一是提供認證的認證過濾器。我發現當一個新的登錄請求(沒有以前的會話)被調用,但是當請求來到已經登錄的用戶,即一個會話存在時,那麼認證過濾器就不會被調用。我沒有找到'springsecurity'在哪裏以及如何跳過這個身份驗證已登錄的請求。請幫我理解這一點。springSecurityFilterChain如何跳過已登錄請求的身份驗證

感謝

回答

0

我覺得SessionManagementFilter注意到了這一問題:

 if (!securityContextRepository.containsContext(request)) { 
     Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 

     if (authentication != null && !authenticationTrustResolver.isAnonymous(authentication)) { 
     // The user has been authenticated during the current request, so call the session strategy 
      try { 
       sessionAuthenticationStrategy.onAuthentication(authentication, request, response); 
      } catch (SessionAuthenticationException e) { 
       // The session strategy can reject the authentication 
       logger.debug("SessionAuthenticationStrategy rejected the authentication object", e); 
       SecurityContextHolder.clearContext(); 
       failureHandler.onAuthenticationFailure(request, response, e); 

       return; 
      } 
      // Eagerly save the security context to make it available for any possible re-entrant 
      // requests which may occur before the current request completes. SEC-1396. 
      securityContextRepository.saveContext(SecurityContextHolder.getContext(), request, response); 
     } else { 
     // No security context or authentication present. Check for a session timeout 
      if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) { 
       if(logger.isDebugEnabled()) { 
        logger.debug("Requested session ID " + request.getRequestedSessionId() + " is invalid."); 
       } 

       if (invalidSessionStrategy != null) { 
        invalidSessionStrategy.onInvalidSessionDetected(request, response); 
        return; 
       } 
      } 
     } 
    } 

當然還有更多在這裏比滿足眼睛。該認證被保存在一個ThreadLocal:

在Spring Security,用於存儲請求之間SecurityContext的責任落到了SecurityContextPersistenceFilter,默認存儲上下文HTTP請求之間的一個HttpSession屬性。它會將每個請求的上下文恢復到SecurityContextHolder,並且在請求完成時關鍵地清除SecurityContextHolder。出於安全目的,您不應該直接與HttpSession進行交互。沒有理由這麼做 - 總是使用SecurityContextHolder來代替。

因此,SecurityContextPersistenceFilter負責加載上下文數據(稍後將其擦除),過濾器鏈中的其他模塊將根據此數據做出決定。 (例如,跳過或通過的UserManager服務做認證)

我不是一個SpringSecurity開發商,所以採取這種信息作爲一個受過教育的猜測僅僅:)

+0

感謝您的回覆,我會研究它。 – Chakri

0

它是一個由三個Filters的組合處理:

0

當對安全對象發出請求時,SessionManagementFilter會查看SecurityContextRepository。如果其內容與SecurityContextHolder相匹配,則它假定該用戶之前已進行身份驗證(如記住我或預先身份驗證)。

如果存儲庫包含安全上下文,則此過濾器不執行任何操作。

如果它什麼都沒有,並且ThreadLocal包含一個認證對象,它假定以前的過濾器以某種方式認證了這個用戶。

0

httpSessionIntegrationFilter照顧這個。它負責維護來自同一用戶的請求之間的會話。