原文地址:https://docs.spring.io/spring-security/site/docs/4.2.6.RELEASE/reference/htmlsingle/#authorization
一个典型的Web应用程序的身份验证过程:
- 您访问主页,然后点击链接。
- 请求发送到服务器,并且服务器确定您已请求受保护的资源。
- 由于您目前没有通过身份验证,因此服务器会发回一个响应,指出您必须进行身份验证。响应可能是HTTP响应代码,也可能是重定向到特定网页。
- 根据身份验证机制,您的浏览器将重定向到特定网页,以便填写表单,或者浏览器以某种方式检索您的身份(通过BASIC身份验证对话框,Cookie,X.509证书等) )。
- 浏览器会发回一个响应给服务器。这将是一个HTTP POST,其中包含您填写的表单的内容,或者包含您的验证细节的HTTP标头。
- 接下来,服务器将决定提交的凭证是否有效。如果它们有效,下一步就会发生。如果它们无效,通常你的浏览器会被要求重试(所以你回到上面的第二步)。
- 您重做的原始请求将导致身份验证过程。希望您已通过足够的授权机构进行身份验证,以访问受保护的资源。如果您有足够的访问权限,请求将会成功。否则,您将收到一个HTTP错误代码403,意思是“禁止”。
Spring Security具有不同的类,负责上述大多数步骤。主要参与者(在使用它们的顺序)是ExceptionTranslationFilter
,一个AuthenticationEntryPoint
和“验证机制”,它负责调用AuthenticationManager
。
1 ExceptionTranslationFilter
ExceptionTranslationFilter
是一个Spring Security过滤器,负责检测抛出的任何Spring Security异常。这种例外情况通常会由AbstractSecurityInterceptor
授权服务的主要提供者 - 一个引发。我们将AbstractSecurityInterceptor
在下一节讨论,但现在我们只需要知道它会产生Java异常,并且对HTTP没有任何认识,或者如何去认证一个主体。相反,ExceptionTranslationFilter
该服务提供此服务,具体负责返回错误代码403(如果委托人已经过身份验证,因此根本没有足够的访问权限 - 按照上面的第7步),或者启动一个AuthenticationEntryPoint
(如果委托人未经过身份验证,因此我们需要开始第三步)。
该AuthenticationEntryPoint
负责第三步在上面的列表中。正如你可以想象的那样,每个Web应用程序都会有一个默认的身份验证策略(当然,这可以像Spring Security中的其他任何东西一样配置,但现在让我们保持简单)。每个主要认证系统都有其自己的AuthenticationEntryPoint
实施,通常执行步骤3中描述的操作之一。
一旦您的浏览器提交了您的身份验证凭证(无论是作为HTTP表单发布还是HTTP标头),服务器上都需要有一些“收集”这些身份验证信息的东西。到目前为止,我们正在上面的列表中的第六步。在Spring Security中,我们为从用户代理(通常是Web浏览器)收集验证信息的功能提供了一个特殊的名称,称之为“验证机制”。示例是基于表单的登录和基本身份验证。一旦从用户代理收集了认证详细信息,Authentication
就会构建一个“请求”对象并呈现给该用户代理AuthenticationManager
。
在认证机制接收到完全填充的Authentication
对象之后,它将认为请求有效,将其Authentication
放入SecurityContextHolder
并导致原始请求被重试(上面的步骤7)。另一方面,如果AuthenticationManager
拒绝请求,认证机制将要求用户代理重试(上面的第二步)。
根据应用程序的类型,可能需要制定一个策略来存储用户操作之间的安全上下文。在典型的Web应用程序中,用户登录一次,随后通过其会话ID进行标识。服务器缓存持续时间会话的主要信息。在Spring Security中,存储SecurityContext
请求之间的责任归属于SecurityContextPersistenceFilter
默认情况下,将上下文存储为HttpSession
HTTP请求之间的属性。它SecurityContextHolder
为每个请求恢复上下文,并且关键地清除SecurityContextHolder
请求完成的时间。HttpSession
出于安全目的,您不应直接与之交互。这样做根本没有理由 - 总是使用它SecurityContextHolder
。
许多其他类型的应用程序(例如,无状态的RESTful Web服务)不使用HTTP会话,并将在每个请求中重新进行身份验证。但是,SecurityContextPersistenceFilter
包含在链中以确保SecurityContextHolder
在每次请求后清除它仍然很重要。
在单个会话中接收并发请求的应用程序中,同一个 |