Spring Security(二十九):9.4.1 ExceptionTranslationFilter

ExceptionTranslationFilter is a Spring Security filter that has responsibility for detecting any Spring Security exceptions that are thrown. Such exceptions will generally be thrown by an AbstractSecurityInterceptor, which is the main provider of authorization services. We will discuss AbstractSecurityInterceptor in the next section, but for now we just need to know that it produces Java exceptions and knows nothing about HTTP or how to go about authenticating a principal. Instead the ExceptionTranslationFilter offers this service, with specific responsibility for either returning error code 403 (if the principal has been authenticated and therefore simply lacks sufficient access - as per step seven above), or launching an AuthenticationEntryPoint (if the principal has not been authenticated and therefore we need to go commence step three).web

ExceptionTranslationFilter是一個Spring Security過濾器,負責檢測拋出的任何Spring Security異常。 AbstractSecurityInterceptor一般會拋出此類異常,後者是受權服務的主要提供者。咱們將在下一節討論AbstractSecurityInterceptor,可是如今咱們只須要知道它產生Java異常而且對HTTP沒有任何瞭解或者如何對主體進行身份驗證。相反,ExceptionTranslationFilter提供此服務,特別負責返回錯誤代碼403(若是主體已通過身份驗證,所以根本沒有足夠的訪問權限 - 按照上面的第7步),或者啓動AuthenticationEntryPoint(若是主體未通過身份驗證,所以咱們須要開始第三步)。

9.4.2 AuthenticationEntryPoint

The AuthenticationEntryPoint is responsible for step three in the above list. As you can imagine, each web application will have a default authentication strategy (well, this can be configured like nearly everything else in Spring Security, but let’s keep it simple for now). Each major authentication system will have its own AuthenticationEntryPoint implementation, which typically performs one of the actions described in step 3.瀏覽器

AuthenticationEntryPoint負責上面列表中的第三步。能夠想象,每一個Web應用程序都有一個默認的身份驗證策略(好吧,這能夠像Spring Security中的其餘幾乎同樣進行配置,但如今讓它保持簡單)。每一個主要身份驗證系統都有本身的AuthenticationEntryPoint實現,該實現一般執行步驟3中描述的操做之一。

9.4.3 Authentication Mechanism

Once your browser submits your authentication credentials (either as an HTTP form post or HTTP header) there needs to be something on the server that "collects" these authentication details. By now we’re at step six in the above list. In Spring Security we have a special name for the function of collecting authentication details from a user agent (usually a web browser), referring to it as the "authentication mechanism". Examples are form-base login and Basic authentication. Once the authentication details have been collected from the user agent, an Authentication "request" object is built and then presented to the AuthenticationManager.緩存

一旦您的瀏覽器提交您的身份驗證憑據(做爲HTTP表單帖子或HTTP標頭),服務器上就須要「收集」這些身份驗證詳細信息。到目前爲止,咱們已經在上面的列表中的第六步了。在Spring Security中,咱們有一個特殊的名稱,用於從用戶代理(一般是Web瀏覽器)收集身份驗證詳細信息,並將其稱爲「身份驗證機制」。例如基於表單的登陸和基自己份驗證。一旦從用戶代理收集了身份驗證詳細信息,就會構建身份驗證「請求」對象,而後將其提供給AuthenticationManager。
 
After the authentication mechanism receives back the fully-populated  Authentication object, it will deem the request valid, put the  Authentication into the  SecurityContextHolder, and cause the original request to be retried (step seven above). If, on the other hand, the  AuthenticationManager rejected the request, the authentication mechanism will ask the user agent to retry (step two above).
在認證機制收到徹底填充的Authentication對象後,它將認爲請求有效,將Authentication放入SecurityContextHolder,並使原始請求重試(上面的步驟7)。另外一方面,若是AuthenticationManager拒絕了請求,則認證機制將要求用戶代理重試(上面的步驟2)。

9.4.4 Storing the SecurityContext between requests

Depending on the type of application, there may need to be a strategy in place to store the security context between user operations. In a typical web application, a user logs in once and is subsequently identified by their session Id. The server caches the principal information for the duration session. In Spring Security, the responsibility for storing the SecurityContext between requests falls to the SecurityContextPersistenceFilter, which by default stores the context as an HttpSessionattribute between HTTP requests. It restores the context to the SecurityContextHolder for each request and, crucially, clears the SecurityContextHolder when the request completes. You shouldn’t interact directly with the HttpSession for security purposes. There is simply no justification for doing so - always use the SecurityContextHolder instead.安全

根據應用程序的類型,可能須要採用策略來在用戶操做之間存儲安全上下文。在典型的Web應用程序中,用戶登陸一次,而後由其會話ID標識。服務器緩存持續時間會話的主體信息。在Spring Security中,在請求之間存儲SecurityContext的責任屬於SecurityContextPersistenceFilter,它默認將上下文存儲爲HTTP請求之間的HttpSession屬性。它爲每一個請求恢復SecurityContextHolder的上下文,而且相當重要的是,在請求完成時清除SecurityContextHolder。出於安全目的,您不該直接與HttpSession交互。沒有理由這樣作 - 老是使用SecurityContextHolder。
 
Many other types of application (for example, a stateless RESTful web service) do not use HTTP sessions and will re-authenticate on every request. However, it is still important that the  SecurityContextPersistenceFilter is included in the chain to make sure that the  SecurityContextHolder is cleared after each request.
許多其餘類型的應用程序(例如,無狀態RESTful Web服務)不使用HTTP會話,並將在每一個請求上從新進行身份驗證。可是,在鏈中包含SecurityContextPersistenceFilter以確保在每次請求後清除SecurityContextHolder仍然很重要。
 
In an application which receives concurrent requests in a single session, the same  SecurityContext instance will be shared between threads. Even though a  ThreadLocal is being used, it is the same instance that is retrieved from the  HttpSession for each thread. This has implications if you wish to temporarily change the context under which a thread is running. If you just use  SecurityContextHolder.getContext(), and call  setAuthentication(anAuthentication) on the returned context object, then the  Authentication object will change in  all concurrent threads which share the same SecurityContext instance. You can customize the behaviour of SecurityContextPersistenceFilter to create a completely new SecurityContext for each request, preventing changes in one thread from affecting another. Alternatively you can create a new instance just at the point where you temporarily change the context. The method SecurityContextHolder.createEmptyContext() always returns a new context instance.
在單個會話中接收併發請求的應用程序中,將在線程之間共享相同的SecurityContext實例。即便正在使用ThreadLocal,它也是從HttpSession爲每一個線程檢索的相同實例。若是您但願臨時更改運行線程的上下文,則會產生影響。若是您只使用SecurityContextHolder.getContext(),並在返回的上下文對象上調用setAuthentication(anAuthentication),則Authentication對象將在共享同一SecurityContext實例的全部併發線程中更改。您能夠自定義SecurityContextPersistenceFilter的行爲,以便爲每一個請求建立一個全新的SecurityContext,從而防止一個線程中的更改影響另外一個線程。或者,您能夠在臨時更改上下文的位置建立新實例。 SecurityContextHolder.createEmptyContext()方法始終返回新的上下文實例。
相關文章
相關標籤/搜索