Spring Security简述

官网地址Architecture :: Spring Security

首先在官网下载示例

Hello Spring Security :: Spring Security

 

项目的代码非常简单,只有一个启动类,跑起来后会显示

Using generated security password: 47277899-ee11-44ca-b7fc-50c1001da7ab

这是因为SpringBoot自动配置的原因。Spring Boot自动为我们配置了bean。

启用Spring Security的预设设定,此设定会将Servlet过滤器建立为名为springSecurityFilterChain的Bean。此Bean负责应用程序中的所有安全性(保护应用程序URL、验证提交的用户名和密码、重定向到登录表单等)。 使用user的用户名和随机生成的密码创建UserDetailsService Bean,该密码将记录到控制台。 在Servlet容器中为每个请求注册名为springSecurityFilterChain的Bean的过滤器(Filter)。

Spring Boot配置不多,但它做了很多。功能概述如下:

  • 需要经过身份验证的用户才能与应用程序进行任何交互

  • 为您生成默认登录表单

  • 让用户使用用户名user和登录到控制台的密码进行基于表单的身份验证(在前面的示例中,密码为47277899-ee11-44ca-b7fc-50c1001da7ab)

  • 使用BCrypt保护密码存储

  • 允许用户注销

  • CSRF攻击预防

  • 会话固定保护

  • 安全标头集成

  • 安全请求的HTTP严格传输安全

  • X-Content-Type-Options集成

  • 缓存控制(稍后可以由应用程序覆盖,以允许缓存静态资源)

  • X-XSS保护集成

  • X-Frame-Options集成有助于防止点击劫持

与以下Servlet API方法集成:

HttpServletRequest#getRemoteUser()

HttpServletRequest.html#getUserPrincipal()

HttpServletRequest.html#isUserInRole(java.lang.String)

HttpServletRequest.html#login(java.lang.String,java.lang.String)

HttpServletRequest.html#logout()

A Review of Filters

过滤器概述

Spring Security的Servlet支持是基于Servlet过滤器的,因此首先大致了解一下过滤器的作用是很有帮助的。下图显示了单个HTTP请求的处理程序的典型分层。

 

客户端向应用程序发送一个请求,容器创建一个FilterChain(过滤器链),它包含Filter实例和Servlet,这些实例和Servlet将根据请求URI的路径处理HttpServletRequest。在Spring MVC应用程序中,Servlet是DispatcherServlet的实例。一个Servlet最多只能处理一个HttpServletRequest和HttpServletResponse。但是,可以使用多个过滤器来:

  • 防止调用下游Filter实例或Servlet。 在这种情况下,Filter通常会写入HttpServletResponse

  • 修改被下游过滤器实例和Servlet使用的 HttpServletRequest 或者 HttpServletResponse

DelegatingFilterProxy

委托过滤器代理

Spring提供了一个名为DelegatingFilterProxy的Filter实现,它允许在Servlet容器的生命周期和Spring的ApplicationContext之间建立桥接。Servlet容器允许使用其自己的标准注册Filter实例,但它不知道Spring定义的Bean。您可以通过标准Servlet容器机制注册DelegatingFilterProxy,但将所有工作委托给实现Filter的Spring Bean。

 

DelegatingFilterProxy的另外一个好处是 它允许延迟查找 Filter bean 实例. 这很重要因为容器需要在能启动前注册Filter 实例. 然而Spring通常使用一个ContextLoaderListener去加载Spring的bean,这直到需要注册Filter实例后才完成。(Filter懒加载)

FilterChainProxy

过滤器链代理

Spring Security的Servlet支持被包含在FilterChainProxy中。FilterChainProxy 是Spring Security提供的一个特殊的Filter,它允许通过SecurityFilterChain委托(选择)许多Filter实例。由于FilterChainProxy是一个bean,它通常被打包在一个DelegatingFilterProxy中。

下图展示了FilterChainProxy的角色

 

SecurityFilterChain

安全过滤器链

SecurityFilterChain is used by FilterChainProxy to determine which Spring Security Filter instances should be invoked for the current request.

FilterChainProxy使用SecurityFilterChain来确定应为当前请求调用哪些Spring安全过滤器实例。

FilterChainProxy使用SecurityFilterChain来决定哪些Spring Security Filter 实例对于当前请求来说应该被调用。

 

在SecurityFilterChain中的Security Filter通常是bean,但是它们是被FilterChainProxy注册而不是DelegatingFilterProxy。FilterChainProxy直接向Servlet容器或DelegatingFilterProxy注册有许多优点。首先,他提供了一个面向所有SpringSecurity的Servlet支持的起点。因为这个原因,如果你想找到Spring Security的 Servlet 支持中的问题,添加一个断点在FilterChainProxy中是一个很好的开始位置。(SpringSecurity的Servlet支持大致意思是SpringSecurity提供的支持Servlet标准(Servlet、Filter)的bean)

其次,由于FilterChainProxy 是使用Spring Security的中心,因此它可以执行不被视为可选的任务。例如,它可以清除SecurityContext以避免内存泄漏。它还可以应用Spring Security的HttpFirewall来保护应用程序免受某些类型的攻击。

 

在上图中,FilterChainProxy决定哪些SecurityFilterChain应被使用。 只有第一个匹配到的SecurityFilterChain被调用。 如果URL/api/message/被请求,则它首先匹配SecurityFilterChain0的模板路径/api/**,所以只有SecurityFilterChain0被调用,尽管它同样匹配SecurityFilterChainn,如果一个为/messages/的路径被请求,它不匹配SecurityFilterChain0中的模板路径/api/**,所以FilterChainProxy 继续尝试每个SecurityFilterChain,假设没有其他SecurityFilterChain实例匹配,SecurityFilterChainn将被调用。

注意SecurityFilterChain0只有三个security Filter被配置,然而SecurityFilterChainn有四个security Filter实例被配置,记住每个SecurityFilterChain能够独立存在并且可以隔离地配置是很重要的。事实上,如果应用程序想忽略某些确定的请求时,一个SecurityFilterChain可能一个security Filter实例都没有。

Security Filters

安全过滤器

Security Filters通过 SecurityFilterChain API被插入到FilterChainProxy中。Filter实例的执行顺序很重要。通常来说,知道Spring Security的Filter实例的顺序是不必要的,然而,有时候知道顺序是很有好处的。

以下是SpringSecurityFilter执行顺序的完整列表:

Handling Security Exceptions

处理安全异常

ExceptionTranslationFilter允许将AccessDeniedExceptionAuthenticationException 转换为HTTP响应。

ExceptionTranslationFilter作为 Security Filters之一被插入到FilterChainProxy中,下图展示了ExceptionTranslationFilter 和其他组件之间的关系:

 

  • 首先ExceptionTranslationFilter调用FilterChain.doFilter(request, response)去调用程序的其他部分(也就是放行)

  • 如果用户是未经过认证的或者它是一个认证异常,那么就开始认证

    • SecurityContextHolder被清除

    • HttpServletRequest被保存,所以在认证成功后可以用来重放原始请求。

  • AuthenticationEntryPoint用于从客户端请求凭据。例如,它可能重定向到登录页面或发送“WWW-Authenticate”标头。

    • 否则,如果他是一个AccessDeniedException那么就拒绝请求,然后AccessDeniedHandler被调用来处理请求被拒绝。

提示:如果应用程序未引发AccessDeniedException或AuthenticationException,则ExceptionTranslationFilter不会执行任何操作。

ExceptionTranslationFilter 的伪代码如下:

 try {
     filterChain.doFilter(request, response);//尝试放行
 } catch (AccessDeniedException | AuthenticationException ex) {//抓取异常
     if (!authenticated || ex instanceof AuthenticationException) {//判断异常类型
         startAuthentication();//开始认证
     } else {
         accessDenied();//拒绝请求
     }
 }

Saving Requests Between Authentication

认证过程中保存请求

如“处理SecurityException”中所示,当请求没有身份验证并且是针对需要身份验证的资源时,需要保存请求,以便在身份验证成功后重新请求已验证的资源。在SpringSecurity中,这是通过使用RequestCache实现保存HttpServletRequest来完成的。

RequestCache

请求缓存

HttpServletRequest保存在RequestCache中。当用户成功进行身份验证时,RequestCache将用于重放原始请求。RequestCacheAwareFilter使用RequestCache保存HttpServletRequest。 默认情况下,使用HttpSessionRequestCache。下面的代码演示了如何自定义RequestCache实现,如果存在名为continue的参数,则该实现用于检查HttpSession中保存的请求。

RequestCacheAwareFilter

请求缓存感知过滤器

RequestCacheAwareFilter使用RequestCache保存HttpServletRequest。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值