Spring Security介绍

  • 开源
  • 提供企业级的安全认证和授权

Spring安全拦截器

  • 认证管理器

    • 认证模式

      • Basic

        HTTP 1.0中使用的认证方法,使用用户名和密码Base64编码的方式

        浏览器弹出对话框,用户输入用户名和密码,加入头部

        无状态

        安全性不足

      • Digest

        解决安全性问题

        浏览器对用户名和密码请求方法,URL等进行MD5运算,发送到服务器

        服务器获取到用户名密码,请求方法,URL等MD5运算,查看是否相等

        安全性问题依然存在

      • X.509

  • 访问决策管理器

  • 运行身份管理器

常用权限拦截器

Spring-Security拦截器链流程图

介绍几个常用的Filter

  1. SecurityContextPersistenceFilter

    基于ThreadLocal

  2. LogoutFilter

    发送注销请求时,清空用户的session,cookie,重定向

  3. AbstractAuthenticationProcessingFilter

    用户登录的请求

  4. DefaultLoginPageGeneratingFilter

    生成登录页面

  5. BasicAuthencationFilter

  6. SecurityContextHolderAwareRequestFilter

    包装,提供额外的数据

  7. RememberMeAuthemticationFilter

    提供RememberMe功能,当cookie中存在rememberme时,登录成功后生成唯一cookie

  8. ExceptionTranlationFilter

    请求到对应的页面,响应异常

    ExceptionTranslationFilter异常处理过滤器,该过滤器用来处理在系统认证授权过程中抛出的异常(也就是下一个过滤器FilterSecurityInterceptor),主要是 处理 AuthenticationExceptionAccessDeniedException

  9. SessionManagerFilter

  10. FilterSecurityInterceptor(授权)

    用户没有登录,抛出未登录异常

    用户登录,但是没有权限访问该资源,抛出拒绝访问的异常

    用户登录,有权限,则放行

    此过滤器为认证授权过滤器链中最后一个过滤器,该过滤器之后就是请求真正的 服务

Filter如何执行

FilterChainProxy会按照顺序调用一组Filter,完成授权验证

请求首先经过Servlet Filter链,这里面包含6个Filter

可以看到如下的一个Filter

ApplicationFilterConfig[name=springSecurityFilterChain, filterClass=org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean$1]

这个就是Spring Security Filter的入口,它的类型是DelegationFilterProxy

那么,这个DelegationFilterProxy到底执行了什么样的操作呢?可以简单看一下源码

重点看一下部分的源码:

public class DelegatingFilterProxy extends GenericFilterBean {

    // 类中的属性
@Nullable
private String contextAttribute; @Nullable
private WebApplicationContext webApplicationContext; @Nullable
private String targetBeanName; private boolean targetFilterLifecycle = false; /**
* 重点在于这个属性
*/
@Nullable
private volatile Filter delegate; private final Object delegateMonitor = new Object(); @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException { // Lazily initialize the delegate if necessary.
Filter delegateToUse = this.delegate;
if (delegateToUse == null) {
synchronized (this.delegateMonitor) {
delegateToUse = this.delegate;
if (delegateToUse == null) {
WebApplicationContext wac = findWebApplicationContext();
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: " +
"no ContextLoaderListener or DispatcherServlet registered?");
}
delegateToUse = initDelegate(wac);
}
this.delegate = delegateToUse;
}
} // Let the delegate perform the actual doFilter operation.
invokeDelegate(delegateToUse, request, response, filterChain);
}
// ....... /**
* Initialize the Filter delegate, defined as bean the given Spring
* application context.
* <p>The default implementation fetches the bean from the application context
* and calls the standard {@code Filter.init} method on it, passing
* in the FilterConfig of this Filter proxy. * @param wac the root application context
* @return the initialized delegate Filter
* @throws ServletException if thrown by the Filter
*/
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
String targetBeanName = getTargetBeanName();
Assert.state(targetBeanName != null, "No target bean name set");
Filter delegate = wac.getBean(targetBeanName, Filter.class);
if (isTargetFilterLifecycle()) {
delegate.init(getFilterConfig());
}
return delegate;
} // 调用delegate的doFilter方法
protected void invokeDelegate(
Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException { delegate.doFilter(request, response, filterChain);
}
}

根据以上代码的注释我们可以看出大概的执行流程

那类中的Filter delegate是什么呢?断点调式运行可以找到以下东西

这是Spring Security 提供的一个FilterChainProxy,关注其中的关键源码

public class FilterChainProxy extends GenericFilterBean {

    // 包含一组SecurityFilterChain
private List<SecurityFilterChain> filterChains; @Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
if (clearContext) {
try {
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
doFilterInternal(request, response, chain);
}
finally {
SecurityContextHolder.clearContext();
request.removeAttribute(FILTER_APPLIED);
}
}
else {
doFilterInternal(request, response, chain);
}
} private void doFilterInternal(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException { FirewalledRequest fwRequest = firewall
.getFirewalledRequest((HttpServletRequest) request);
HttpServletResponse fwResponse = firewall
.getFirewalledResponse((HttpServletResponse) response); // 根据请求获取匹配的一组Filter
// 这里返回的Filter就是上述的那些AuthenticationFilter,比如UsernamePasswordAuthenticationFilter
List<Filter> filters = getFilters(fwRequest); if (filters == null || filters.size() == 0) {
if (logger.isDebugEnabled()) {
logger.debug(UrlUtils.buildRequestUrl(fwRequest)
+ (filters == null ? " has no matching filters"
: " has an empty filter list"));
} fwRequest.reset(); chain.doFilter(fwRequest, fwResponse); return;
} VirtualFilterChain vfc = new VirtualFilterChain(fwRequest, chain, filters);
vfc.doFilter(fwRequest, fwResponse);
} /**
* Returns the first filter chain matching the supplied URL.
*
* @param request the request to match
* @return an ordered array of Filters defining the filter chain
*/
private List<Filter> getFilters(HttpServletRequest request) {
for (SecurityFilterChain chain : filterChains) {
if (chain.matches(request)) {
return chain.getFilters();
}
} return null;
} }

到此,我们可以总结出如下的流程图:

Spring Security 介绍的更多相关文章

  1. Spring Security 介绍与Demo

    一.Spring Security 介绍 Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块的默认技术选型.我们仅需引入spring-boot-s ...

  2. Spring Security安全框架入门篇

    一.Spring Security相关概念 1.1..Spring Security介绍: Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安 ...

  3. Spring Security +Oauth2 +Spring boot 动态定义权限

    Oauth2介绍:Oauth2是为用户资源的授权定义了一个安全.开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是安全的. 简单的来说,当用户登陆网站的时候,需要账号 ...

  4. 「快学springboot」集成Spring Security实现鉴权功能

    Spring Security介绍 Spring Security是Spring全家桶中的处理身份和权限问题的一员.Spring Security可以根据使用者的需要定制相关的角色身份和身份所具有的权 ...

  5. SpringBoot集成Spring Security

    1.Spring Security介绍 Spring security,是一个强大的和高度可定制的身份验证和访问控制框架.它是确保基于Spring的应用程序的标准 --来自官方参考手册 Spring ...

  6. Java安全框架(一)Spring Security

    Java安全框架(一)Spring Security ​ 文章主要分三部分 1.Spring Security的架构及核心组件:(1)认证:(2)权限拦截:(3)数据库管理:(4)权限缓存:(5)自定 ...

  7. 权限管理3-整合Spring Security

    一.Spring Security介绍 1.框架介绍 Spring 是一个非常流行和成功的 Java 应用开发框架.Spring Security 基于 Spring 框架,提供了一套 Web 应用安 ...

  8. Spring Security探究之路之开始

    前言 在Spring Security介绍中,我们分析到了根据请求获取匹配的SecurityFilterChain,这个类中包含了一组Filter 接下来我们从这些Filter开始探究之旅 Sprin ...

  9. Spring Security 与 OAuth2 介绍

    个人 OAuth2 全部文章 Spring Security 与 OAuth2(介绍):https://www.jianshu.com/p/68f22f9a00ee Spring Security 与 ...

随机推荐

  1. 自定义djangorestframework-simplejwt的验证表

    django restframework-simplejwt默认是通过调用django的get_user_model方法来得到验证表的表名,然后再通过查询id来验证是否有这个用户. 当需要自定义用户表 ...

  2. Linux设置新的服务器登录端口

    root用户登录服务器 22端口修改为22525,22端口也打开,以防新端口设置有问题,登录不上服务器 向防火墙中添加修改的端口 systemctl start firewalld firewall- ...

  3. MySQL 开启和关闭远程访问

    MySQL 开启和关闭远程访问权限 一.开启MySQL/MariaDB的远程访问权限 [root@localhost ~]# mysql -u root -p MariaDB [(none)]> ...

  4. Python调用aiohttp

    1. aiohttp安装 pip install aiohttp 1.1. 基本请求用法 async with aiohttp.get('https://github.com') as r: awai ...

  5. CSS中inherit指定继承的使用方法和auto的区别

    CSS中的每个属性都有一个特定值"inherit",其含义是指定继承父元素的相应属性,使用inherit一方面在代码上能地表明要继承于父元素的样式属性,另一方面也使子元素继承了那些 ...

  6. Apache Shiro反序列化远程代码执行复现

    最近也是看shiro漏洞比较多,所以自己也在本地复现了一下,拿出来与大家一起分享 0x00 关于Apache Shiro Apache shiro是一个Java安全框架,提供了认证.授权.加密和会话管 ...

  7. 生产环境上,哨兵模式集群Redis版本升级应用实战

    背景: 由于生产环境上所使用的Redis版本并不一致,好久也没有更新,为了避免版本不同对Redis集群造成影响,从而升级为统一Redis版本! 1.集群架构 一主两从三哨兵: 2.升级方案 (1)升级 ...

  8. vue传参子传父

    vue子传父用$emit实现 1.文件目录结构 2.parent父组件内容 <template> <div class="wrap"> <div> ...

  9. Ajax_同源策略以及跨域问题

    Ajax_同源策略 同源策略是浏览器的一种安全策略, 同源指的是:协议.域名.端口.必须完全相同. 违背同源策略就是跨域. 而AJAX是默认遵循同源策略的: 同源说通俗一点呢就是页面跟获取请求的接口是 ...

  10. 2022GDUT寒假专题学习-1 B,F,I,J题

    专题链接:专题学习1 - Virtual Judge (vjudge.net) B - 全排列 题目 思想 这道题可以用DFS进行求解,但是一看到全排列,其实可以立刻想到一个STL函数:next_pe ...