spring security官方文档详解之Servlet应用程序

1.详情请参见spring security官方文档之Servlet应用程序
2.详情请参看spring security官方api文档

文章目录

      • 一.简介
      • 二.开始/入门
        • 2.1 更新依赖项
        • 2.2 启动示例程序
        • 2.3 Spring Boot自动配置
      • 三.体系结构
        • 3.1 过滤器综述
        • 3.2 DelegatingFilterProxy
        • 3.3 FilterChainProxy
        • 3.4 SecurityFilterChain(安全过滤器链)
        • 3.5 Security Filters(安全过滤器)
        • 3.6 Handling Security Exceptions(处理安全异常)
      • 四.Authentication(身份验证)
        • 4.1 Authentication Mechanisms(身份验证机制)
        • 4.2 Servlet Authentication Architecture(Servlet身份验证体系结构)
          • 4.2.1 SecurityContextHolder
          • 4.2.2 SecurityContext
          • 4.2.3 Authentication(身份验证)
          • 4.2.4 GrantedAuthority(授权)
          • 4.2.5 AuthenticationManager
          • 4.2.6 ProviderManager
          • 4.2.7 AuthenticationProvider
          • 4.2.8 Request Credentials with AuthenticationEntryPoint
          • 4.2.9 AbstractAuthenticationProcessingFilter
        • 4.3 Username/Password Authentication(用户名/密码身份验证)
          • 4.3.1 Form Login(表单登录)
          • 4.3.2 Basic Authentication(基本HTTP认证支持)
        • 4.4 password storage(密码存储)
          • 4.4.1 In-Memory Authentication(内存身份验证)
          • 4.4.2 JDBC Authentication(JDBC身份验证,略,请参看官方文档)
          • 4.4.3 UserDetails
          • 4.4.4 UserDetailsService
          • 4.4.5 PasswordEncoder(密码编码器)
          • 4.4.6 DaoAuthenticationProvider
        • 4.5 Session Management(会话管理)
          • 4.5.1 Detecting Timeouts(检测超时)
          • 4.5.2 Concurrent Session Control(并发会话控制)
          • 4.5.3 Session Fixation Attack Protection(会话固定攻击保护)
          • 4.5.4 SessionAuthenticationStrategy/并发控制/在SessionRegistry中查询当前经过身份验证的用户及其会话(略,请参看官方文档)
        • 4.6 Remember-Me Authentication/OpenID Support/Anonymous Authentication/Pre-Authentication Scenarios/Java Authentication and Authorization Service (JAAS) Provider/CAS Authentication/X.509 Authentication(略,请参看官方文档)
        • 4.7 Run-As Authentication Replacement
        • 4.8 Handling Logouts(处理登出)
          • 4.8.1 LogoutHandler
          • 4.8.2 LogoutSuccessHandler
        • 4.9 Authentication Events(身份验证事件)
      • 五.Authorization(授权)
        • 5.1 Authorization Architecture(授权架构)
          • 5.1.1 Pre-Invocation Handling(预调用/调用前处理)
          • 5.1.2 The AuthorizationManager
          • 5.1.3 Delegate-based AuthorizationManager Implementations(基于委托的AuthorizationManager实现)
        • 5.2 Authorize HttpServletRequests with AuthorizationFilter(使用AuthorizationFilter授权HttpServletRequests)
        • 5.3 Authorize HttpServletRequest with FilterSecurityInterceptor(使用FilterSecurity Interceptor授权HttpServletRequest)
        • 5.4 Expression-Based Access Control(基于表达式的访问控制)
          • 5.4.1 常见的内置表达式
          • 5.4.2 在Web安全表达式中引用bean
          • 5.4.3 Web安全表达式中的路径变量
          • 5.4.4 Method Security Expressions(方法安全表达式)
            • 5.4.4.1 @Pre and @Post Annotations
            • 5.4.4.2 使用@PreAuthorize和@PostAuthorize进行访问控制
            • 5.4.4.3 使用@PreFilter和@PostFilter进行过滤
            • 5.4.4.4 The PermissionEvaluator interface
        • 5.5 Secure Object Implementations(安全对象实现)
          • 5.5.1 AOP Alliance (MethodInvocation) Security Interceptor
          • 5.5.2 AspectJ (JoinPoint) Security Interceptor
        • 5.6 Method Security(方法安全)
          • 5.6.1 EnableMethodSecurity
          • 5.6.2 EnableGlobalMethodSecurity
          • 5.6.3 GlobalMethodSecurityConfiguration(全局方法安全配置)
      • 六.Protection Against Exploits(防止利用漏洞)
        • 6.1 Cross Site Request Forgery (CSRF) for Servlet Environments(Servlet环境的跨站点请求伪造(CSRF))
          • 6.1.1 使用Spring Security的CSRF保护的步骤如下:
          • 6.1.2 禁用 CSRF 保护
          • 6.1.3 包含 CSRF 令牌
        • 6.2 Security HTTP Response Headers(安全HTTP响应头)
          • 6.2.1 Default Security Headers(默认安全标头)
      • 七.Java配置
        • 7.1 多个 HttpSecurity
      • 八.OAuth2(待补充....)

一.简介

1.Spring Security通过使用一个标准的Servlet过滤器与Servlet容器集成。这意味着它可以与任何运行在Servlet容器中的应用程序一起工作。更具体地说,您不需要在基于servlet的应用程序中使用Spring来利用Spring Security。

2.章节摘要

  • 开始/入门
  • 体系结构
  • 身份验证
  • 授权
  • OAuth2
  • SAML2
  • 防止利用漏洞
  • 集成
  • 配置
  • 附录

二.开始/入门

本节介绍如何在Spring Boot中使用Spring Security的最小设置。您可以通过点击这里下载一个最小的Spring Boot + Spring Security应用程序。

2.1 更新依赖项

您需要做的唯一一步就是使用Maven或Gradle更新依赖项。

2.2 启动示例程序

spring security官方文档详解之Servlet应用程序_第1张图片

2.3 Spring Boot自动配置

1.Spring Boot自动地

  • 启用Spring Security的默认配置,该配置将创建一个servlet过滤器(作为名为springSecurityFilterChain的bean)。这个bean负责应用程序内的所有安全性(保护应用程序URL、验证提交的用户名和密码、重定向到登录表单等)
  • 创建一个UserDetailsService bean,其用户名为user,并随机生成一个登录到控制台的密码
  • 为每个请求向Servlet容器注册一个名为springSecurityFilterChain的bean的Filter

2.Spring Boot没有太多配置,但它做了很多。这些功能的摘要如下:

  • 与应用程序的任何交互都需要一个经过身份验证的用户。
  • 为您生成一个默认的登录表单。
  • 让用户名为user的用户和登录到控制台的密码通过基于表单的身份验证进行身份验证。
  • 使用BCrypt保护密码存储
  • 允许用户登出
  • CSRF攻击预防
  • Session Fixation protection(会话固定保护)
  • Security Header integration(安全头集成)
  • HTTP为安全请求提供严格的传输安全性
  • X-Content-Type-Options集成
  • 缓存控制(稍后可以被你的应用程序覆盖,以允许缓存你的静态资源)
  • X-XSS-Protection集成
  • X-Frame-Options集成有助于防止点击劫持
  • 集成以下Servlet API方法:HttpServletRequest#getRemoteUser();HttpServletRequest#getUserPrincipal();HttpServletRequest#isUserInRole(java.lang.String);HttpServletRequest#login(java.lang.String, java.lang.String);HttpServletRequest#logout()

三.体系结构

本节讨论Spring Security在基于Servlet的应用程序中的高级体系结构。我们将在身份验证、授权、防止利用漏洞部分建立这种高层次理解。

3.1 过滤器综述

Spring Security的Servlet支持基于Servlet过滤器,因此首先了解过滤器的作用是很有帮助的。下图显示了单个HTTP请求的典型处理程序分层。客户端向应用程序发送一个请求,容器创建一个FilterChain,其中包含过滤器和Servlet,这些过滤器和Servlet应该根据请求URI的路径处理HttpServletRequest。在Spring MVC应用程序中,Servlet是DispatcherServlet的一个实例。最多一个Servlet可以处理单个HttpServletRequest和HttpServletResponse。但是,可以使用多个过滤器来:

  • 防止下游过滤器或Servlet被调用。在这种情况下,过滤器通常会写入HttpServletResponse
  • 修改下游过滤器和Servlet使用的HttpServletRequest或HttpServletResponse

因为过滤器只影响下游的过滤器和Servlet,所以每个Filter被调用的顺序是非常重要的。

spring security官方文档详解之Servlet应用程序_第2张图片

3.2 DelegatingFilterProxy

1.Spring提供了一个名为DelegatingFilterProxy的过滤器实现,它允许在Servlet容器的生命周期和Spring的ApplicationContext之间进行桥接。Servlet容器允许使用它自己的标准注册过滤器,但它不知道Spring定义的bean。DelegatingFilterProxy可以通过标准的Servlet容器机制注册,但将所有工作委托给实现过滤器的Spring bean。以下是DelegatingFilterProxy如何融入过滤器和过滤器链的图片。
spring security官方文档详解之Servlet应用程序_第3张图片

2.DelegatingFilterProxy从ApplicationContext中查找Bean Filter0,然后调用Bean Filter0。DelegatingFilterProxy的伪代码如下所示。DelegatingFilterProxy的另一个好处是,它允许延迟查找Filter bean实例。This is important because the container needs to register the Filter instances before the container can startup。然而,Spring通常使用ContextLoaderListener来加载Springbean->直到过滤器实例需要被注册之后才会加载。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
	// Lazily get Filter that was registered as a Spring Bean
	// For the example in DelegatingFilterProxy
	// delegate is an instance of Bean Filter0
	Filter delegate = getFilterBean(someBeanName);
	// delegate work to the Spring Bean
	delegate.doFilter(request, response);
}

3.3 FilterChainProxy

1.Spring Security的Servlet支持包含在FilterChainProxy中。FilterChainProxy是Spring Security提供的一个特殊的过滤器,它允许通过SecurityFilterChain委托给多个过滤器实例。由于FilterChainProxy是一个Bean,它通常被包装在一个DelegatingFilterProxy中
spring security官方文档详解之Servlet应用程序_第4张图片

3.4 SecurityFilterChain(安全过滤器链)

1.FilterChainProxy使用SecurityFilterChain来决定应该为此请求调用哪些Spring Security Filters。

2.SecurityFilterChain中的安全过滤器(Security Filters)通常是bean,but they are registered with FilterChainProxy instead of DelegatingFilterProxy。FilterChainProxy provides a number of advantages to registering directly with the Servlet container or DelegatingFilterProxy。首先,它为所有Spring Security的Servlet支持提供了一个起点。其次,由于FilterChainProxy是Spring Security使用的核心,它可以执行不被视为可选的任务。例如,它清除SecurityContext以避免内存泄漏。它还应用Spring Security的HttpFirewall来保护应用程序免受某些类型的攻击。此外,它在决定何时应该调用SecurityFilterChain提供了更大的灵活性。在Servlet容器中,仅基于URL调用过滤器。然而,FilterChainProxy可以通过利用RequestMatcher接口,根据HttpServletRequest中的任何内容确定调用。事实上,FilterChainProxy可以用来确定决定使用哪个SecurityFilterChain。这允许为应用程序的不同部分提供完全独立的配置。

spring security官方文档详解之Servlet应用程序_第5张图片
3.在多个SecurityFilterChain图中,FilterChainProxy决定应该使用哪个SecurityFilterChain。只有第一个匹配的SecurityFilterChain将被调用。如果请求的URL为/api/messages/,它将首先匹配SecurityFilterChain0,因此仅调用SecurityFilterChain0,即使它也匹配SecurityFilterChainn。如果请求了/messages/的URL,它与SecurityFilterChain0的/api/**模式不匹配,因此FilterChainProxy将继续尝试每个SecurityFilterChain。Assuming that no other, SecurityFilterChain instances match SecurityFilterChainn will be invoked.。请注意,SecurityFilterChain0只配置了三个安全过滤器实例。但是,SecurityFilterChainn配置了四个安全过滤器。需要注意的是,每个SecurityFilterChain都可以是唯一的,并且可以单独配置。事实上,如果应用程序希望Spring security忽略某些请求,SecurityFilterChain可能没有安全过滤器。
spring security官方文档详解之Servlet应用程序_第6张图片

3.5 Security Filters(安全过滤器)

1.安全过滤器通过SecurityFilterChain API被插入到FilterChainProxy中。过滤器的顺序很重要。通常不需要知道Spring Security过滤器的顺序。然而,有时了解顺序是有益的。以下是Spring Security Filter排序的综合列表:
spring security官方文档详解之Servlet应用程序_第7张图片
spring security官方文档详解之Servlet应用程序_第8张图片

3.6 Handling Security Exceptions(处理安全异常)

1.ExceptionTranslationFilter允许将AccessDeniedException和AuthenticationException转换为HTTP响应。ExceptionTranslationFilter作为安全过滤器之一被插入到FilterChainProxy中。

2.如下图

  1. 首先,ExceptionTranslationFilter调用FilterChain.doFilter(request, response)调用应用程序的其余部分。
  2. 如果用户未经身份验证或者它是一个AuthenticationException,则启动身份验证。(1)SecurityContextHolder被清除。(2)HttpServletRequest保存在RequestCache中。当用户成功进行身份验证时,将使用RequestCache重播原始请求。(3)AuthenticationEntryPoint用于从客户端请求凭据。例如,它可能会重定向到一个登录页面或发送一个WWW-Authenticate报头
  3. 否则,如果是AccessDeniedException,则拒绝访问。将调用AccessDeniedHandler来处理被拒绝的访问

spring security官方文档详解之Servlet应用程序_第9张图片
3.伪代码如下图
spring security官方文档详解之Servlet应用程序_第10张图片

四.Authentication(身份验证)

1.Spring Security为身份验证提供了全面的支持。我们首先讨论整个Servlet身份验证体系结构。

4.1 Authentication Mechanisms(身份验证机制)

  • Username and Password - how to authenticate with a username/password
  • OAuth 2.0 Login - OAuth 2.0 Log In with OpenID Connect and non-standard OAuth 2.0 Login (i.e. GitHub)
  • SAML 2.0 Login - SAML 2.0 Log In
  • Central Authentication Server (CAS) - Central Authentication Server (CAS) Support
  • Remember Me - how to remember a user past session expiration
  • JAAS Authentication - authenticate with JAAS
  • OpenID - OpenID Authentication (not to be confused with OpenID Connect)
  • Pre-Authentication Scenarios - authenticate with an external mechanism such as SiteMinder or Java EE security but still use Spring Security for authorization and protection against common exploits.
  • X509 Authentication - X509 Authentication

4.2 Servlet Authentication Architecture(Servlet身份验证体系结构)

在Servlet身份验证中使用的Spring Security的主要架构组件。

  • SecurityContextHolder——SecurityContextHolder是Spring Security存储身份验证人员详细信息的地方。
  • SecurityContext——从SecurityContextHolder获取,包含当前已验证用户的Authentication。
  • Authentication——
  • GrantedAuthority——在身份验证中被授予主体(principal)的权限(即角色、范围等)。
  • AuthenticationManager——定义Spring Security过滤器如何执行身份验证的API。
  • ProviderManager——AuthenticationManager最常见的实现。
  • AuthenticationProvider——由ProviderManager用于执行特定类型的身份验证。
  • Request Credentials with AuthenticationEntryPoint——用于从客户端请求凭据(即重定向到登录页面、发送WWW-Authenticate响应等)
  • AbstractAuthenticationProcessingFilter——用于身份验证的基本过滤器。这也很好地说明了身份验证的高级流程以及各个部分是如何协同工作的。
4.2.1 SecurityContextHolder

spring security官方文档详解之Servlet应用程序_第11张图片
1.Spring Security认证模型的核心是SecurityContextHolder。它包含SecurityContext。SecurityContextHolder是Spring Security存储身份验证人员详细信息的地方。Spring Security不关心SecurityContextHolder是如何被填充的。如果它包含一个值,那么它将被用作当前经过身份验证的用户。

2.如果您希望获取已身份验证的主体(principal)的信息,可以通过访问SecurityContextHolder来获取。默认情况下,SecurityContextHolder使用ThreadLocal存储这些细节,这意味着SecurityContext始终可用于同一线程中的方法,即使SecurityContext没有显式地作为参数传递给这些方法。如果在处理当前主体的请求后小心地清除线程,那么以这种方式使用ThreadLocal是非常安全的。Spring Security的FilterChainProxy确保SecurityContext总是被清除。有些应用程序并不完全适合使用ThreadLocal,because of the specific way they work with threads。

spring security官方文档详解之Servlet应用程序_第12张图片
spring security官方文档详解之Servlet应用程序_第13张图片

4.2.2 SecurityContext

SecurityContext是从SecurityContextHolder获得的。SecurityContext包含一个Authentication对象。

4.2.3 Authentication(身份验证)

1.在Spring Security中,Authentication有两个主要目的:

  • AuthenticationManager的输入,用于提供用户为进行身份验证而提供的凭据。在此场景中使用时,isAuthenticated()返回false
  • 表示当前已身份验证的用户。当前的Authentication可以从SecurityContext获得

2.Authentication包含:

  • principal-标识用户。当使用用户名/密码进行身份验证时,这通常是UserDetails的一个实例
  • credentials-通常是密码。在许多情况下,这将在用户经过身份验证后清除,以确保不会泄露
  • authorities-"GrantedAuthority"是授予用户的高级权限。角色或范围就是一个例子。
4.2.4 GrantedAuthority(授权)

1.可以通过Authentication.getAuthorities()方法获取GrantedAuthoritys(被授予的权限)。此方法提供GrantedAuthority对象的集合。被授予的权限是授予principal的权限。这种权限通常是“角色”,如ROLE_ADMINISTRATOR或ROLE_HR_SUPERVISOR。这些角色稍后将配置为web授权、方法授权和域对象授权。使用基于用户名/密码的身份验证时,授予的权限通常由UserDetailsService加载。

2.通常,GrantedAuthority对象是应用程序范围的权限。它们不是特定于给定的域对象的。因此,您不太可能有一个GrantedAuthority来表示对编号为54的Employee对象的权限,因为如果有数千个这样的权限,您将很快耗尽内存(或者,至少会导致应用程序花很长时间对用户进行身份验证)

4.2.5 AuthenticationManager

1.AuthenticationManager是定义Spring Security的过滤器如何执行身份验证的API。返回的Authentication是由调用AuthenticationManager的控制器(例如Spring Security的过滤器)在SecurityContextHolder上设置的。如果你没有集成Spring Security的过滤器,你可以直接设置SecurityContextHolder,而不需要使用AuthenticationManager。虽然AuthenticationManager的实现可以是任何东西,但最常见的实现是ProviderManager。

4.2.6 ProviderManager

1.ProviderManager是AuthenticationManager最常用的实现。ProviderManager委托给AuthenticationProviders列表。每个AuthenticationProvider都有机会表明身份验证应该成功、失败,或者表明它无法做出决定,并允许下游AuthenticationProvider做出决定。如果配置的AuthenticationProviders都无法进行身份验证,则身份验证将失败,出现ProviderNotFoundException,这是一种特殊的身份验证异常,表明ProviderManager没有配置为支持传递给它的身份验证类型。
spring security官方文档详解之Servlet应用程序_第14张图片
2.实际上,每个AuthenticationProvider都知道如何执行特定类型的身份验证。例如,一个AuthenticationProvider可能能够验证用户名/密码,而另一个可能能够验证SAML断言。这允许每个AuthenticationProvider执行特定类型的身份验证,同时支持多种类型的身份验证,并且只公开一个AuthenticationManager bean。ProviderManager还允许配置一个可选的父级AuthenticationManager,在没有AuthenticationProvider可以执行身份验证的情况下,可以咨询该父级AuthenticationManager。父级可以是任何类型的AuthenticationManager,但它通常是ProviderManager的一个实例。

spring security官方文档详解之Servlet应用程序_第15张图片
3.事实上,多个ProviderManager实例可能共享同一个父AuthenticationManager。这在有多个SecurityFilterChain实例的场景中比较常见,这些实例有一些共同的身份验证(共享的父AuthenticationManager),但也有不同的身份验证机制(不同的ProviderManager实例)。
spring security官方文档详解之Servlet应用程序_第16张图片
4.默认情况下,ProviderManager将尝试从成功的身份验证请求返回的Authentication对象中清除任何敏感凭据信息。这防止像密码这样的信息在HttpSession中被保留的时间超过必要的时间

4.2.7 AuthenticationProvider

1.多个AuthenticationProvider可以被注入到ProviderManager中。每个AuthenticationProvider执行特定类型的身份验证。例如,DaoAuthenticationProvider支持基于用户名/密码的身份验证,而JwtAuthenticationProvider支持对JWT令牌进行身份验证。

4.2.8 Request Credentials with AuthenticationEntryPoint

1.AuthenticationEntryPoint用于发送从客户端请求凭据的HTTP响应。有时,客户端会主动包含用户名/密码等凭据来请求资源,在这些情况下,Spring Security不需要提供从客户端请求凭据的HTTP响应,因为它们已经包含在内了。在其他情况下,客户端将向未经授权访问的资源发出未经身份验证的请求,AuthenticationEntryPoint的实现用于从客户端请求凭据。AuthenticationEntryPoint实现可能会重定向到一个登录页面,响应一个WWW-Authenticate头等等

4.2.9 AbstractAuthenticationProcessingFilter

1.AbstractAuthenticationProcessingFilter被用作验证用户凭据的基本过滤器在对凭据进行身份验证之前,Spring Security通常使用AuthenticationEntryPoint请求凭据。接下来,AbstractAuthenticationProcessingFilter可以对提交给它的任何身份验证请求进行身份验证。

2.如下图

  1. 当用户提交他们的凭据时,AbstractAuthenticationProcessingFilter从要进行身份验证的HttpServletRequest中创建一个身份验证。创建的身份验证类型取决于AbstractAuthenticationProcessingFilter的子类。例如,UsernamePasswordAuthenticationFilter从HttpServletRequest中提交的用户名和密码创建一个UsernamePasswordAuthenticationToken。
  2. 第2步,身份验证被传递到AuthenticationManager进行身份验证
  3. 如果身份验证失败,则失败:(1)SecurityContextHolder被清除。(2)RememberMeServices.loginFail被调用。如果没有配置remember me,则无操作。(3)AuthenticationFailureHandler被调用
  4. 如果身份验证成功,则成功:(1)SessionAuthenticationStrategy收到新登录的通知。(2)Authentication在SecurityContextHolder上设置的。稍后,SecurityContextPersistenceFilter将SecurityContext保存到HttpSession(3)RememberMeServices.loginSuccess被调用。如果没有配置remember me,则无操作。(4)ApplicationEventPublisher发布一个InteractiveAuthenticationSuccessEvent。(5)
    AuthenticationSuccessHandler被调用

spring security官方文档详解之Servlet应用程序_第17张图片

4.3 Username/Password Authentication(用户名/密码身份验证)

1.验证用户身份最常见的方法之一是验证用户名和密码。

2.Spring Security为从HttpServletRequest读取用户名和密码提供了以下内置机制:

  • Form Login(表单登录)
  • Basic Authentication
  • Digest Authentication
4.3.1 Form Login(表单登录)

1.Spring Security支持通过html表单提供用户名和密码。让我们看看Spring Security中基于表单的登录是如何工作的。首先,我们看到用户是如何被重定向到登录表单的。

  1. 首先,用户向未授权的资源/private发出未经身份验证的请求。
  2. Spring Security的FilterSecurityInterceptor通过抛出一个AccessDeniedException来表示未经验证的请求被拒绝
  3. 由于用户没有通过身份验证,ExceptionTranslationFilter开始启动身份验证,并通过配置的AuthenticationEntryPoint向登录页面发送一个重定向。在大多数情况下,AuthenticationEntryPoint是LoginUrlAuthenticationEntryPoint的一个实例
  4. 浏览器会请求它被重定向到的登录页面。
  5. 应用程序中的某些东西,必须呈现登录页面。

spring security官方文档详解之Servlet应用程序_第18张图片
spring security官方文档详解之Servlet应用程序_第19张图片

2.当用户名和密码被提交时,UsernamePasswordAuthenticationFilter将验证用户名和密码。UsernamePasswordAuthenticationFilter扩展了AbstractAuthenticationProcessingFilter。

  1. 当用户提交用户名和密码时,UsernamePasswordAuthenticationFilter会创建一个UsernamePasswordAuthenticationToken,这是一种通过从HttpServletRequest中提取用户名和密码的身份验证类型
  2. UsernamePasswordAuthenticationToken被传递到AuthenticationManager进行身份验证。AuthenticationManager的详细信息取决于用户信息的存储方式
  3. 同4.2.8节
  4. 同4.2.8节

spring security官方文档详解之Servlet应用程序_第20张图片

3.默认情况下启用SpringSecurity表单登录。然而,只要提供了任何基于servlet的配置,就必须显式地提供基于表单的登录。如下图在此配置中,Spring Security将呈现一个默认的登录页面。
spring security官方文档详解之Servlet应用程序_第21张图片

4.大多数生产应用程序都需要自定义登录表单。下面的配置演示了如何提供自定义登录表单。
spring security官方文档详解之Servlet应用程序_第22张图片

5.当在SpringSecurity配置中指定登录页面时,您负责呈现该页面。下面是一个Thymeleaf模板,它生成一个HTML登录表单,该表单符合/login的登录页面:
spring security官方文档详解之Servlet应用程序_第23张图片

6.如果您正在使用Spring MVC,您将需要一个将GET /login映射到我们创建的登录模板的控制器。
spring security官方文档详解之Servlet应用程序_第24张图片

4.3.2 Basic Authentication(基本HTTP认证支持)

1.本节详细介绍了Spring Security如何为基于servlet的应用程序提供基本HTTP认证支持。让我们看看HTTP Basic Authentication在Spring Security中是如何工作的。首先,我们看到WWW-Authenticate报头被发送回未经身份验证的客户端。

  1. 首先,用户向未授权的资源/private发出未经验证的请求。
  2. Spring Security的FilterSecurityInterceptor通过抛出一个AccessDeniedException来表示未经验证的请求被拒绝。
  3. 由于用户没有通过身份验证,ExceptionTranslationFilter开始启动身份验证。配置的AuthenticationEntryPoint是BasicAuthenticationEntryPoint的一个实例,它发送一个WWW-Authenticate报头。RequestCache通常是一个不保存请求的NullRequestCache,因为客户端能够重放它最初请求的请求
  4. 当客户端收到WWW Authenticate标头时,它知道应该使用用户名和密码重试。下面是正在处理的用户名和密码的流程。

spring security官方文档详解之Servlet应用程序_第25张图片
spring security官方文档详解之Servlet应用程序_第26张图片

2.当客户端收到WWW-Authenticate报头时,它知道应该使用用户名和密码重试。下面是正在处理的用户名和密码的流程。与4.3.1大体相同

  1. BasicAuthenticationFilter会创建一个UsernamePasswordAuthenticationToken。
  2. (1)…(2)…(3)AuthenticationEntryPoint被调用以触发再次发送WWW-Authenticate。
  3. (1)…(2)…(3)BasicAuthenticationFilter调用FilterChain.doFilter(request,response)来继续应用程序逻辑的其余部分。

spring security官方文档详解之Servlet应用程序_第27张图片
3.默认情况下,Spring Security的HTTP Basic Authentication支持是启用的。然而,只要提供了任何基于servlet的配置,就必须显式地提供HTTP Basic。
spring security官方文档详解之Servlet应用程序_第28张图片

4.4 password storage(密码存储)

1.存储机制
每个受支持的读取用户名和密码的机制都可以利用任何受支持的存储机制:

  1. Simple Storage with In-Memory Authentication
  2. Relational Databases with JDBC Authentication
  3. Custom data stores with UserDetailsService
  4. LDAP storage with LDAP Authentication
4.4.1 In-Memory Authentication(内存身份验证)

1.Spring Security的InMemoryUserDetailsManager实现了UserDetailsService,为存储在内存中的基于用户名/密码的身份验证提供支持。InMemoryUserDetailsManager通过实现UserDetailsManager接口提供对UserDetails的管理。当Spring Security被配置为接受用户名/密码进行身份验证时,会使用基于UserDetails的身份验证。

4.4.2 JDBC Authentication(JDBC身份验证,略,请参看官方文档)
4.4.3 UserDetails

UserDetails由UserDetailsService返回。DaoAuthenticationProvider验证UserDetails,然后返回一个身份验证,该身份验证的主体(principal)是已配置的UserDetails服务返回的UserDetails。

4.4.4 UserDetailsService

1.DaoAuthenticationProvider使用UserDetailsService来检索检索用户名、密码和其他属性,以便使用用户名和密码进行身份验证。Spring Security提供了UserDetailsService的内存和JDBC实现。你可以通过将自定义UserDetailsService公开为bean来定义自定义身份验证

4.4.5 PasswordEncoder(密码编码器)

1.Spring Security的servlet通过与PasswordEncoder集成,支持安全地存储密码。定制Spring Security使用的PasswordEncoder实现可以通过公开PasswordEncoder Bean来完成。

4.4.6 DaoAuthenticationProvider

1.DaoAuthenticationProvider是一个AuthenticationProvider实现,它利用UserDetailsService和PasswordEncoder来验证用户名和密码。让我们看看DaoAuthenticationProvider在Spring Security中是如何工作的。

  1. 读取用户名和密码的authentication Filter将UsernamePasswordAuthenticationToken传递给由ProviderManager实现的AuthenticationManager。
  2. ProviderManager被配置为使用DaoAuthenticationProvider类型的AuthenticationProvider。
  3. DaoAuthenticationProvider从UserDetailsService中查找UserDetails。
  4. DaoAuthenticationProvider然后使用PasswordEncoder验证在上一步返回的UserDetails上的密码。
  5. 身份验证成功后,返回的身份验证类型为UsernamePasswordAuthenticationToken,其主体(principal)是由已配置的UserDetailsService返回的UserDetails。最终,返回的UsernamePasswordAuthenticationToken将由authentication Filter(身份验证过滤器)在SecurityContextHolder上设置。

spring security官方文档详解之Servlet应用程序_第29张图片

4.5 Session Management(会话管理)

4.5.1 Detecting Timeouts(检测超时)

1.您可以配置Spring Security来检测无效会话(invalid session)ID的提交,并将用户重定向到适当的URL。这是通过session-management元素实现的:
spring security官方文档详解之Servlet应用程序_第30张图片

2.请注意,如果您使用上面这种机制检测会话超时,如果用户登出(log out),然后在没有关闭浏览器的情况下重新登录,则可能会错误地报告错误。这是因为当您使会话无效时,session cookie不会被清除,即使用户已经登出,session cookie也会被重新提交。您可以在登出时显式地删除JSESSIONID cookie,例如,在登出处理程序中使用以下语法:不幸的是,这不能保证适用于每个servlet容器,所以您需要在您的环境中测试它
spring security官方文档详解之Servlet应用程序_第31张图片

4.5.2 Concurrent Session Control(并发会话控制)

1.如果您希望限制单个用户登录应用程序的能力,Spring Security通过以下简单的添加提供了开箱即用的支持。首先,您需要将以下监听器添加到配置中,以保持Spring Security关于会话生命周期事件的更新:
spring security官方文档详解之Servlet应用程序_第32张图片

2.第二次登录将被拒绝。通过“拒绝”,我们的意思是,如果使用基于表单的登录,用户将被发送到身份验证失败url。如果第二次身份验证是通过另一个非交互机制进行的,例如“remember-me”,则将向客户端发送一个“未授权”(401)错误。如果您想使用错误页面,可以将属性session-authentication-error-url添加到session-management元素。如果您正在为基于表单的登录使用定制的身份验证过滤器,那么您必须显式地配置并发会话控制支持。

4.5.3 Session Fixation Attack Protection(会话固定攻击保护)

1.会话固定攻击是一种潜在风险,恶意攻击者可能通过访问站点创建会话,然后说服另一个用户使用同一会话登录(例如,通过向他们发送包含会话标识符作为参数的链接)。Spring Security通过创建一个的新会话或在用户登录时更改会话ID来自动防止这种情况。如果不需要这种保护,或者它与其他一些需求冲突,则可以使用session-management元素上的session-fixation-protection属性来控制行为,该属性有四个选项

  1. none - 什么都不要做。原session将被保留。
  2. newSession - 创建一个新的“干净”会话,而不复制现有会话数据(与Spring security相关的属性仍将被复制)。
  3. migrateSession - 创建一个新会话,并将所有现有会话属性复制到新会话。这是Servlet 3.0或更早版本容器中的默认值。
  4. changeSessionId - 不创建新会话。相反,使用Servlet容器提供的会话固定保护(HttpServletRequest#changeSessionId())。此选项仅在Servlet 3.1(Java EE 7)和更新的容器中可用。

当会话固定保护发生时,它会导致在应用程序上下文中发布SessionFixationProtectionEvent。如果使用changeSessionId,还将导致任何javax.servlet.http.HttpSessionIdListeners被通知,因此如果代码同时侦听这两个事件,请小心。

4.5.4 SessionAuthenticationStrategy/并发控制/在SessionRegistry中查询当前经过身份验证的用户及其会话(略,请参看官方文档)

4.6 Remember-Me Authentication/OpenID Support/Anonymous Authentication/Pre-Authentication Scenarios/Java Authentication and Authorization Service (JAAS) Provider/CAS Authentication/X.509 Authentication(略,请参看官方文档)

4.7 Run-As Authentication Replacement

待补充…

4.8 Handling Logouts(处理登出)

1.当使用WebSecurityConfigurerAdapter时,会自动应用logout功能。默认情况下,访问URL /logout将通过以下方式登出用户:

  • 使HTTP会话无效
  • 清除任何已配置的RememberMe身份验证
  • 清除SecurityContextHolder
  • 重定向到/login?logout

还可以使用各种选项来进一步自定义logout要求:

  1. 提供logout支持。这在使用WebSecurityConfigurerAdapter时自动应用。
  2. 触发logout的URL(默认为/logout)。如果启用了CSRF保护(默认),那么请求也必须是POST。
  3. 登出后要重定向到的URL。默认值是/login?logout。
  4. 让我们指定一个自定义LogoutSuccessHandler。如果指定了此选项,则忽略logoutSuccessUrl()
  5. 指定是否在登出时使HttpSession无效。默认为true。Configures the SecurityContextLogoutHandler under the covers.
  6. 添加一个LogoutHandler。默认情况下,SecurityContextLogoutHandler被添加为最后一个LogoutHandler
  7. 允许指定登出成功时要删除的Cookie的名称。

spring security官方文档详解之Servlet应用程序_第33张图片

4.8.1 LogoutHandler

1.通常,LogoutHandler实现指示能够参与注销处理的类。它们将被调用以执行必要的清理。因此,他们不应该抛出异常。提供了各种实现:

  • PersistentTokenBasedMemberMeservices
  • TokenBasedMemberMeservices
  • CookiecLearningLogoutHandler
  • CsrfLogoutHandler
  • SecurityContextLogoutHandler
  • HeaderWriterLogoutHandler

与直接提供LogoutHandler实现不同,the fluent API还提供了快捷方式,在底层提供了各自的LogoutHandler实现。例如deleteCookies()允许指定一个或多个cookie的名称,以便登出成功时删除。与添加CookieClearingLogoutHandler相比,这是一个快捷方式。

4.8.2 LogoutSuccessHandler

1.LogoutSuccessHandler在成功登出后被LogoutFilter调用,以处理重定向或转发到适当的目的地。请注意,该接口与LogoutHandler几乎相同,但可能会引发异常。提供了以下实现:

  • SimpleUrlLogoutSuccessHandler
  • HttpStatusReturningLogoutSuccessHandler

如上所述,您不需要直接指定SimpleUrlLouguTsuccessHandler。相反,fluent API通过设置logoutSuccessUrl()提供了一个快捷方式。这将在幕后设置SimpleRulloGoutSuccessHandler。登出后,将被重定向到提供的URL。默认值是/login?logout。
在REST API类型的场景中,HttpStatusReturningLogoutSuccessHandler可能很有趣。此LogoutSuccessHandler允许您提供一个要返回的普通HTTP状态码,而不是在成功登出时重定向到一个URL。如果未配置,默认情况下将返回状态代码200。

4.9 Authentication Events(身份验证事件)

1.对于每个成功或失败的身份验证,将分别触发AuthenticationSuccessEvent或AbstractAuthenticationFailureEvent。要监听这些事件,必须首先发布AuthenticationEventPublisher。Spring Security的DefaultAuthenticationEventPublisher可能会做得很好:
spring security官方文档详解之Servlet应用程序_第34张图片

五.Authorization(授权)

5.1 Authorization Architecture(授权架构)

1.身份验证讨论了所有的身份验证实现如何存储一个被授予的权限对象(GrantedAuthority objects)列表。这些代表已授予principal的权限。AuthenticationManager会将GrantedAuthority对象插入到身份验证对象中,然后AuthoricationManager会在做出授权决策时读取这些GrantedAuthority对象
在这里插入图片描述

2.此方法允许AuthorizationManager获得被授权权限的精确字符串表示形式。通过返回一个字符串表示形式,被授予的权限可以很容易地被大多数AuthorizationManagers和AccessDecisionManagers“读取”。如果一个GrantedAuthority不能被精确地表示为字符串,那么这个GrantedAuthority被认为是“复杂的”,并且getAuthority()必须返回null。“复杂”的GrantedAuthority的一个例子是存储适用于不同客户账号的操作和权限阈值列表的实现。将这个复杂的GrantedAuthority表示为字符串将非常困难,因此getAuthority()方法应该返回null。Spring Security包括一个具体的GrantedAuthority实现,SimpleGrantedAuthority。这允许将任何用户指定的字符串转换为GrantedAuthority(被授予的权限)。

5.1.1 Pre-Invocation Handling(预调用/调用前处理)

1.Spring Security提供了拦截器,可以控制对安全对象(如方法调用或web请求等)的访问。关于是否允许调用继续的调用前决定由AccessDecisionManager做出

5.1.2 The AuthorizationManager

1.AuthorizationManager取代AccessDecisionManager和AccessDecisionVoter。建议自定义AccessDecisionManager或AccessDecisionVoter的应用程序改为使用AuthorizationManager。AuthorizationManager由AuthorizationFilter调用,负责做出最终的访问控制决策。AuthorizationManager界面包含两种方法:

  1. check:check方法会传递其做出授权决策(authorization decision)所需的所有相关信息。特别是,传递安全对象(secure object)可以检查实际安全对象调用中包含的参数。例如,假设安全对象是MethodInvocation。可以很容易地在MethodInvocation中查询任何Customer参数,然后在AuthorizationManager中实现某种安全逻辑,以确保主体(principal)被允许进行操作。如果允许访问,则实现将返回肯定的AuthorizationDecision;如果拒绝访问,则实现将返回否定的AuthorizationDecision;如果放弃决策,则实现将返回空的 AuthorizationDecision。
  2. verify:verify调用check,如果是否定的授权决策,则随后抛出AccessDeniedException。

spring security官方文档详解之Servlet应用程序_第35张图片

5.1.3 Delegate-based AuthorizationManager Implementations(基于委托的AuthorizationManager实现)

1.虽然用户可以实现自己的AuthorizationManager来控制授权的所有方面,Spring Security ships with a delegating AuthorizationManager that can collaborate with individual AuthorizationManagers。RequestMatcherDelegatingAuthorizationManager将请求与最合适的委托授权管理器匹配。对于方法安全性,可以使用AuthorizationManagerBeforeMethodInterceptor和AuthorizationManagerAfterMethodInterceptor。使用这种方法,可以根据授权决策对AuthorizationManager实现的组合进行轮询。

  • AuthorityAuthorizationManager:Spring Security提供的最常见的AuthorizationManager是AuthorityAuthorizationManager。它配置了一组给定的权限,以便在当前身份验证中查找。如果身份验证包含任何配置的权限,它将返回肯定的AuthorizationDecision。否则,它将返回否定的AuthorizationDecision。
  • AuthenticatedAuthorizationManager:另一个管理器是AuthenticatedAuthorizationManager。它可以用来区分匿名用户、完全身份验证用户和记住我身份验证用户。许多网站允许在"记住我"身份验证下进行某些有限访问,但要求用户通过登录来确认自己的身份以进行完全访问。
  • Custom Authorization Managers:显然,您还可以实现一个自定义AuthorizationManager,并且您可以在其中放入任何想要的访问控制逻辑。

spring security官方文档详解之Servlet应用程序_第36张图片

5.2 Authorize HttpServletRequests with AuthorizationFilter(使用AuthorizationFilter授权HttpServletRequests)

1.AuthorizationFilter取代FilterSecurity Interceptor。为了保持向后兼容,FilterSecurity Interceptor仍然是默认设置。本节讨论AuthorizationFilter如何工作,以及如何覆盖默认配置。AuthorizationFilter为httpservletrequest提供授权。它作为一个安全过滤器被插入到FilterChainProxy中

2.流程

  1. AuthorizationFilter从SecurityContextHolder获得身份验证。它将其包装到一个Supplier中以延迟查找。
  2. AuthorizationFilter从HttpServletRequest、HttpServletResponse和FilterChain创建一个FilterInvocation。
  3. 它将Supplier< Authentication>和FilterInvocation传递给AuthorizationManager。
  4. 如果授权被拒绝,则抛出AccessDeniedException。在这种情况下,ExceptionTranslationFilter处理AccessDeniedException。
  5. 如果允许访问,AuthorizationFilter将继续使用FilterChain,允许应用程序正常处理。

spring security官方文档详解之Servlet应用程序_第37张图片
3.通过按优先顺序添加更多规则,我们可以将Spring Security配置为具有不同的规则。

  1. 指定了多个授权规则。每个规则都是按照它们被声明的顺序来考虑的。
  2. 我们指定了任意用户都可以访问的多个URL模式。具体来说,如果URL以“/resources/”开头、等于“/signup”或等于“/about”,任何用户都可以访问请求。
  3. 任何以“/admin/”开头的URL将仅限于具有“ROLE_ADMIN”角色的用户。您会注意到,由于我们调用的是hasRole方法,所以不需要指定“ROLE_”前缀。
  4. 任何以“/db/”开头的URL都要求用户同时拥有“ROLE_ADMIN”和“ROLE_DBA”。您会注意到,因为我们使用的是hasRole表达式,所以不需要指定“ROLE_”前缀。
  5. 任何尚未匹配的URL都将被拒绝访问。如果您不想意外忘记更新授权规则,这是一个很好的策略。

spring security官方文档详解之Servlet应用程序_第38张图片
4.你可以采用一种基于bean的方法,构造你自己的RequestMatcherDelegatingAuthorizationManager
spring security官方文档详解之Servlet应用程序_第39张图片
5.下面是一个将自定义授权管理器映射到my/authorized/endpoint的示例:
spring security官方文档详解之Servlet应用程序_第40张图片

5.3 Authorize HttpServletRequest with FilterSecurityInterceptor(使用FilterSecurity Interceptor授权HttpServletRequest)

1.FilterSecurity Interceptor正在被AuthorizationFilter替换。考虑使用它。FilterSecurity Interceptor为HttpServletRequests提供授权。它作为安全过滤器之一插入FilterChainProxy

2.流程

  1. FilterSecurityInterceptor从SecurityContextHolder获得身份验证。
  2. FilterSecurityInterceptor从传递到FilterSecurityInterceptor的HttpServletRequest、HttpServletResponse和FilterChain创建FilterInvocation。
  3. 它将FilterInvocation传递给SecurityMetadataSource以获取ConfigAttributes。
  4. 它将身份验证、FilterInvocation和ConfigAttribute传递到AccessDecisionManager。
  5. 如果授权被拒绝…
  6. 如果允许访问…

spring security官方文档详解之Servlet应用程序_第41张图片
spring security官方文档详解之Servlet应用程序_第42张图片
spring security官方文档详解之Servlet应用程序_第43张图片

5.4 Expression-Based Access Control(基于表达式的访问控制)

Spring Security使用Spring EL来提供表达式支持,表达式使用“根对象”作为计算上下文的一部分进行计算。Spring Security使用特定的web和方法安全类作为根对象,以便提供内置表达式和对值的访问,如当前主体(current principal)。

5.4.1 常见的内置表达式

spring security官方文档详解之Servlet应用程序_第44张图片
spring security官方文档详解之Servlet应用程序_第45张图片

5.4.2 在Web安全表达式中引用bean

如果希望扩展可用的表达式,可以很容易地引用您公开的任何Springbean。例如,假设您有一个名为webSecurity的Bean,它包含以下方法签名:
spring security官方文档详解之Servlet应用程序_第46张图片

5.4.3 Web安全表达式中的路径变量

有时,能够在URL中引用路径变量(path variables)是件好事。例如,考虑一个RESTful应用程序,它以格式/user/{userId}从URL路径中根据ID查找用户。你可以通过将path变量放置在pattern中很容易地引用它。例如,如果您有一个名为webSecurity的Bean,它包含以下方法签名:
spring security官方文档详解之Servlet应用程序_第47张图片

5.4.4 Method Security Expressions(方法安全表达式)

方法安全性比简单的允许或拒绝规则要复杂一些。为了全面支持表达式的使用,Spring Security 3.0引入了一些新的注释。

5.4.4.1 @Pre and @Post Annotations

有四个注释支持表达式属性,以允许调用前和调用后的授权检查,并且还支持对提交的集合参数或返回值进行过滤。它们是@PreAuthorize、@PreFilter、@PostAuthorize和@PostFilter

5.4.4.2 使用@PreAuthorize和@PostAuthorize进行访问控制

1.最明显有用的注释是@PreAuthorize,它决定一个方法是否可以被调用。如下代码,这意味着只有角色为“ROLE_USER”的用户才能访问。
在这里插入图片描述

2.如下代码,这里我们实际上使用一个方法参数作为表达式的一部分,to decide whether the current user has the “admin” permission for the given contact。内置的hasPermission()表达式通过应用程序上下文链接到Spring Security ACL模块
在这里插入图片描述

3.Spring Security可以通过多种方式解析方法参数。Spring Security使用DefaultSecurityParameterNameDiscoveryr来发现参数名。默认情况下,将对整个方法尝试以下选项。

  • 如果Spring Security的@P注释出现在该方法的单个参数上,则将使用该值。在幕后,这是使用AnnotationParameterNameDiscoverer实现的,它可以自定义以支持任何指定注释的value属性。
  • 如果Spring Data的@Param注释至少存在于该方法的一个参数上,则将使用该值。在幕后,这是使用AnnotationParameterNameDiscoverer实现的,它可以自定义以支持任何指定注释的value属性。

spring security官方文档详解之Servlet应用程序_第48张图片
spring security官方文档详解之Servlet应用程序_第49张图片

4.任何Spring-EL功能都可以在表达式中使用,因此您还可以访问参数的属性。例如,如果您希望特定的方法只允许访问用户名与联系人匹配的用户,则可以这样写:这里我们访问的是另一个内置表达式authentication,它是存储在安全上下文中的身份验证。你还可以使用表达式principal直接访问其“principal”属性。该值通常是一个UserDetails实例,因此可以使用principal之类的表达式。比如principal.username or principal.enabled。
在这里插入图片描述

5.不太常见的情况是,您可能希望在调用该方法后执行访问控制检查。这可以通过@PostAuthorize注释实现。要从方法访问返回值,请在表达式中使用内置名称returnObject

5.4.4.3 使用@PreFilter和@PostFilter进行过滤

Spring Security支持使用表达式过滤集合、数组、映射和流。这通常在方法的返回值上执行。例如:当使用@PostFilter注释时,Spring Security将遍历返回的集合或映射,并删除提供的表达式为false的任何元素。您还可以使用@PreFilter在方法调用之前进行过滤,尽管这是一个不太常见的需求。请注意,过滤显然不能代替调整数据检索查询。如果要过滤大型集合并删除许多条目,那么这可能效率低下。
在这里插入图片描述

5.4.4.4 The PermissionEvaluator interface

hasPermission()表达式被委托给PermissionEvaluator的一个实例。它旨在连接expression系统和Spring Security的ACL系统,允许您基于抽象权限指定域对象的授权约束。它对ACL模块没有显式的依赖关系,因此如果需要,您可以将其替换为其他实现。该接口有两种方法:
在这里插入图片描述

5.5 Secure Object Implementations(安全对象实现)

5.5.1 AOP Alliance (MethodInvocation) Security Interceptor

方法安全性是使用MethodSecurityInterceptor强制执行的,它保护MethodInvocations(方法调用)的安全。拦截器使用MethodSecurityMetadataSource实例获取应用于特定方法调用的配置属性。

5.5.2 AspectJ (JoinPoint) Security Interceptor

AspectJ拦截器被命名为AspectJSecurityInterceptor。Unlike the AOP Alliance security interceptor, which relies on the Spring application context to weave in the security interceptor via proxying(通过代理), the AspectJSecurityInterceptor is weaved in via the AspectJ compiler。在同一个应用程序中使用这两种类型的安全拦截器并不少见,AspectJSecurityInterceptor用于域对象实例安全,AOP Alliance MethodSecurityInterceptor用于服务层安全

5.6 Method Security(方法安全)

5.6.1 EnableMethodSecurity

1.在Spring Security 5.6中,我们可以在任何@Configuration实例上使用@EnableMethodSecurity注释来启用基于注释的安全性。这在许多方面改进了@EnableGlobalMethodSecurity。@EnableMethodSecurity:

  1. 使用简化的AuthorizationManager API,而不是元数据源、配置属性、decision managers(决策管理器)和voters(投票者)。这简化了重用和定制。
  2. 支持直接基于bean的配置,而不是需要扩展GlobalMethodSecurityConfiguration来定制bean
  3. 是使用原生Spring AOP构建的,消除了抽象,并允许您使用Spring AOP构建块进行自定义
  4. 检查有无冲突的annotations(注释),以确保明确的安全配置
  5. 符合JSR-250标准
  6. 默认启用@PreAuthorize、@PostAuthorize、@PreFilter和@PostFilter

2.您可以使用以下方法启用对Spring Security的@Secured注释的支持:
在这里插入图片描述

5.6.2 EnableGlobalMethodSecurity

1.我们可以在任何@Configuration实例上使用@EnableGlobalMethodSecurity注释来启用基于注释的安全性。例如,下面将启用Spring Security的@Secured注释。
spring security官方文档详解之Servlet应用程序_第50张图片

2.要使用新的基于表达式的语法,可以使用
spring security官方文档详解之Servlet应用程序_第51张图片

5.6.3 GlobalMethodSecurityConfiguration(全局方法安全配置)

有时,您可能需要执行比@EnableGlobalMethodSecurity注释允许的操作更复杂的操作。对于这些实例,您可以扩展GlobalMethodSecurity配置,确保子类上存在@EnableGlobalMethodSecurity注释。例如,如果希望提供自定义MethodSecurityExpressionHandler,可以使用以下配置:
spring security官方文档详解之Servlet应用程序_第52张图片

六.Protection Against Exploits(防止利用漏洞)

本节讨论特定于Servlet的对Spring Security防止常见漏洞攻击的支持。

6.1 Cross Site Request Forgery (CSRF) for Servlet Environments(Servlet环境的跨站点请求伪造(CSRF))

6.1.1 使用Spring Security的CSRF保护的步骤如下:
  • Use proper HTTP verbs
  • 在应用程序中配置Spring Security的CSRF保护:Spring Security的CSRF保护在默认情况下是启用的,但您可能需要自定义配置。
  • 包括CSRF令牌:默认情况下,Spring Security使用HttpSessionsRftokenRepository将预期的CSRF令牌存储在HttpSession中。在某些情况下,用户可能希望配置自定义CsrfTokenRepository。例如,可能需要将CsrfToken持久化到cookie中,以支持基于JavaScript的应用程序。默认情况下,CookieCsrfTokenRepository将写入名为XSRF-TOKEN的cookie,并从名为X-XSRF-TOKEN的报头或HTTP参数_csrf读取它。这些默认值来自AngularJS。下面的示例显式设置cookieHttpOnly=false。这是允许JavaScript(即AngularJS)读取它所必需的。如果不需要使用JavaScript直接读取cookie,建议省略cookieHttpOnly=false以提高安全性。。
    spring security官方文档详解之Servlet应用程序_第53张图片
6.1.2 禁用 CSRF 保护

spring security官方文档详解之Servlet应用程序_第54张图片

6.1.3 包含 CSRF 令牌

为了使同步器令牌模式能够抵御CSRF攻击,我们必须在HTTP请求中包含实际的CSRF令牌。这必须包含在请求的一部分中(即表单参数、HTTP头等),浏览器不会自动将其包含在HTTP请求中。

6.2 Security HTTP Response Headers(安全HTTP响应头)

6.2.1 Default Security Headers(默认安全标头)

1.Spring Security提供了一组默认的安全HTTP响应头,以提供安全的默认值。您可以自定义特定的headers,通过以下配置,您可以轻松做到这一点:
spring security官方文档详解之Servlet应用程序_第55张图片
2.如有必要,可以使用以下配置禁用所有HTTP安全响应头:
spring security官方文档详解之Servlet应用程序_第56张图片

七.Java配置

7.1 多个 HttpSecurity

我们可以配置多个HttpSecurity实例,就像我们可以配置多个http块一样。关键是多次扩展WebSecurity配置适配器。例如,下面是一个对以/api/开头的URL进行不同配置的示例。
spring security官方文档详解之Servlet应用程序_第57张图片

八.OAuth2(待补充…)

Spring Security提供全面的OAuth 2支持。本节讨论如何将OAuth 2集成到基于servlet的应用程序中

你可能感兴趣的:(spring,boot,web安全)