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()方法始终返回新的上下文实例。
相关文章
相关标签/搜索