8.1.4 Authentication in a Web Application
8.1.4 Authentication in a Web Application
Now let’s explore the situation where you are using Spring Security in a web application (without web.xml security enabled). How is a user authenticated and the security context established?
現在讓我們研究一下在web應用程序中使用Spring安全性的情況(沒有web.xml安全啟用)。如何對用戶進行身份驗證并建立安全上下文?
Consider a typical web application’s authentication process:
考慮一個典型的web應用程序的身份驗證過程:
Spring Security has distinct classes responsible for most of the steps described above. The main participants (in the order that they are used) are the ExceptionTranslationFilter, an AuthenticationEntryPoint and an "authentication mechanism", which is responsible for calling the AuthenticationManager which we saw in the previous section.
Spring Security有不同的類負責上面描述的大多數步驟。主要參與者(按使用順序)是ExceptionTranslationFilter、AuthenticationEntryPoint和“身份驗證機制”,該機制負責調用我們在上一節中看到的authenticationmanager。
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).
ExceptionTranslationFilter是一個Spring安全過濾器,它負責檢測拋出的任何Spring安全異常。此類異常通常由AbstractSecurityInterceptor拋出,它是授權服務的主要提供者。我們將在下一節討論AbstractSecurityInterceptor,但是現在我們只需要知道它會產生Java異常,并且不知道HTTP或如何對主體進行身份驗證。相反ExceptionTranslationFilter提供這種服務,具體負責返回錯誤代碼403(如果校長已經過身份驗證的,因此只是缺乏足夠的訪問——按步驟7),或啟動一個AuthenticationEntryPoint(如果委托人還沒有經過身份驗證的,因此我們要開始第三步)。
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中描述的操作之一。
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表單post或HTTP header的形式),服務器上就需要“收集”這些身份驗證細節。到目前為止,我們已經完成了上述列表中的第6步。在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放入SecurityContextHolder中,并導致重新嘗試原始請求(上面的步驟7)。另一方面,如果AuthenticationManager拒絕請求,身份驗證機制將要求用戶代理重試(上面的步驟2)。
Storing the SecurityContext between requests
在請求之間存儲SecurityContext
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 HttpSession attribute 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中為每個線程檢索的實例是相同的。如果您希望臨時更改線程所運行的上下文,那么這將產生影響。如果您只是使用SecurityContext.getcontext(),并對返回的上下文對象調用setAuthentication(anAuthentication),那么身份驗證對象將在共享相同SecurityContext實例的所有并發線程中發生變化。您可以自定義SecurityContextPersistenceFilter的行為,為每個請求創建一個全新的SecurityContext,防止一個線程中的更改影響另一個線程。或者,您可以只在臨時更改上下文的地方創建一個新實例。方法SecurityContextHolder.createemptycontext()總是返回一個新的上下文實例。 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的8.1.4 Authentication in a Web Application的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue工程全局设置ajax的等待动效
- 下一篇: 容器打印日志到控制台阻塞的排障