Spring Security 的工作原理/总体架构

这篇具有很好参考价值的文章主要介绍了Spring Security 的工作原理/总体架构。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1、过滤器的视角

2、DelegatingFilterProxy 委派过滤器代理(类)

2、FilterChainProxy 过滤器链代理(类)

4、SecurityFilterChain 安全过滤器链(接口)

5、Security Filters 安全过滤器实例

6、Spring Security 如何处理安全异常?

7、在认证的时候保存用户请求


        // 释义、解读和思考

1、过滤器的视角

        Spring Security 对 Servlet 支持基于 Servlet 过滤器。下图显示了单个HTTP请求的处理程序的典型分层。

Spring Security 的工作原理/总体架构,Spring Security,spring,spring security

        客户端向应用程序发送请求,容器根据请求 URI 的路径创建一个 FilterChain,其中包含过滤器实例和处理 HttpServletRequest 的 Servlet。// 过滤器链式顺序执行的,具有有序性

        因为 Filter 会影响下游的 Filter 实例和 Servlet,所以调用每个 Filter 的顺序非常重要

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    // 省略...
    chain.doFilter(request, response); 
    // 省略...
}

        // doFilter 方法中有一个 FilterChain 入参,FilterChain 也是一个接口,既然 FilterChain 是一个过滤器链,那么它的实现类中肯定包含有一个 Filter 列表(持有一个或多个Filter 对象)。看源码

        // Spring Security 利用过滤器链来实现身份验证和授权

2、DelegatingFilterProxy 委派过滤器代理(类)

        Spring 提供了一个名为 DelegatingFilterProxy 的过滤器代理类,它是 Servlet 容器的生命周期和 Spring 的 ApplicationContext 之间架桥。//这个类是一个通用的过滤器实例

Spring Security 的工作原理/总体架构,Spring Security,spring,spring security

        // 在Spring 中,Spring 管理过滤器的生命周期,所以 Filter 实例也是 Spring 中的一个Bean

        DelegatingFilterProxy 从 ApplicationContext 中查找 Bean Filter-0,然后调用 Bean Filter-0,下面的代码展示了这一过程:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    //获取Bean
	Filter delegate = getFilterBean(someBeanName);
	delegate.doFilter(request, response);
}

        // 总结:DelegatingFilterProxy 这个类就是一个过滤器实例,Spring 通过这个过滤器,去实现一系列的认证和授权操作。

        // 深刻认识下,想想这种做法。

2、FilterChainProxy 过滤器链代理(类)

        Spring Security 的 Servlet 支持包含在 FilterChainProxy 中。

        FilterChainProxy 是 Spring Security 提供的一个特殊过滤器,它允许通过 SecurityFilterChain 向多个过滤器实例委托。FilterChainProxy 是一个Bean,它通常被封装在 DelegatingFilterProxy中。

Spring Security 的工作原理/总体架构,Spring Security,spring,spring security

        //见名知意,过滤器链的代理 FilterChainProxy 中会持有过滤器链的对象

public class FilterChainProxy extends GenericFilterBean {

	private static final Log logger = LogFactory.getLog(FilterChainProxy.class);

	private final static String FILTER_APPLIED = FilterChainProxy.class.getName().concat(
			".APPLIED");

    // SecurityFilterChain 对象列表
	private List<SecurityFilterChain> filterChains;

    //省略...
}

        // FilterChainProxy -> DelegatingFilterProxy,可以猜想 DelegatingFilterProxy 中的这个 delegate 是不是就是 FilterChainProxy 的实例?源码见分晓

​
public class DelegatingFilterProxy extends GenericFilterBean {
    @Nullable
    private String contextAttribute;
    @Nullable
    private WebApplicationContext webApplicationContext;
    @Nullable
    private String targetBeanName;
    private boolean targetFilterLifecycle;
    @Nullable
    private volatile Filter delegate;  //这里有一个过滤器委托,proxy
    private final Object delegateMonitor;
    //省略...
}

4、SecurityFilterChain 安全过滤器链(接口)

        FilterChainProxy 使用 SecurityFilterChain 来确定应该为当前请求调用哪一个 Spring SecurityFilter 实例

        //选择过滤器链,在FilterChainProxy 中是这样做的

// 返回与提供的URL匹配的第一个过滤器链    
private List<Filter> getFilters(HttpServletRequest request) {
		for (SecurityFilterChain chain : filterChains) {
			if (chain.matches(request)) {
				return chain.getFilters();
			}
		}
		return null;
	}

//一些源码:
//SecurityFilterChain(接口) -> DefaultSecurityFilterChain(实现类) -> 持有RequestMatcher对象 -> matches方法
//RequestMatcher接口用来支持匹配HttpServletRequest的简单策略。匹配策略有很多,此处不多介绍
//RequestMatcher -> AntPathRequestMatcher(实现),servlet通过url路径进行匹配 

        下图显示了 SecurityFilterChain 的角色。

Spring Security 的工作原理/总体架构,Spring Security,spring,spring security

        SecurityFilterChain 中的 Filter 实例是在 FilterChainProxy 中进行注册的(而不是 DelegatingFilterProxy)。

    public FilterChainProxy(SecurityFilterChain chain) {
		this(Arrays.asList(chain));
	}

	public FilterChainProxy(List<SecurityFilterChain> filterChains) {
		this.filterChains = filterChains;
	}

        使用 FilterChainProxy 作为起点的优势://这些特点很重要,仔细看

  1. 这样做为 Spring Security 的所有 Servlet 支持提供了一个起点,如果试图对 Spring Security 的 Servlet 支持进行故障排除,那么在 FilterChainProxy 中添加一个调试点是一个很好的开始。//所有的过滤器都在这里进行注册,然后开始调用,过滤器的调用从FilterChainProxy选择一个过滤器链开始
  2. FilterChainProxy 是 Spring Security 使用的核心,它可以执行一些不可选的任务。例如,清除 SecurityContext 以避免内存泄漏,应用 Spring Security 的HttpFirewall 来保护应用程序免受某些类型的攻击。//不可选的任务,就是必须做的一些事情或者一些通用的功能
  3. 在确定何时调用 SecurityFilterChain 方面提供了更大的灵活性。在 Servlet 容器中,仅根据 URL 调用 Filter 实例。然而,FilterChainProxy 可以通过使用 RequestMatcher 接口,基于 HttpServletRequest 中的任何内容来确定调用。//方便做选择,RequestMatcher -> 匹配策略接口

        下图显示了多个 SecurityFilterChain 实例:

Spring Security 的工作原理/总体架构,Spring Security,spring,spring security

        在 Multiple SecurityFilterChain 图中,FilterChainProxy 决定应该使用哪个 SecurityFilterChain。

        这里有一些匹配规则: 

        FilterChainProxy 只会调用匹配到的第一个 SecurityFilterChain。如请求 URL 为: /api/messages/,它首先匹配的是 SecurityFilterChain-0(匹配规则:/api/**),因此只调用 SecurityFilterChain-0,即使它也匹配 SecurityFilterChain-n(匹配规则:/**)。//执行第一个匹配到的过滤器链

        如果请求 URL/messages/ ,它与SecurityFilterChain-0(匹配规则:/api/**)不匹配,因此 FilterChainProxy 会继续尝试每个 SecurityFilterChain。假设没有其他 SecurityFilterChain 实例匹配,则调用 SecurityFilterChain-n

        需要注意的是,每个 SecurityFilterChain 都是唯一的,并且可以进行单独配置。如果应用程序希望 Spring security 忽略某些请求,那么可以在 SecurityFilterChain 中不设置任何的安全过滤器实例。//SecurityFilterChain 这个里边可以没有任何过滤器,那就是不进行任何拦截

5、Security Filters 安全过滤器实例

        以下是 Spring Security 的过滤器排序的综合列表://按顺序排列的

  1. ForceEagerSessionCreationFilter
  2. ChannelProcessingFilter
  3. WebAsyncManagerIntegrationFilter
  4. SecurityContextPersistenceFilter
  5. HeaderWriterFilter
  6. CorsFilter
  7. CsrfFilter
  8. LogoutFilter
  9. OAuth2AuthorizationRequestRedirectFilter
  10. Saml2WebSsoAuthenticationRequestFilter
  11. X509AuthenticationFilter
  12. AbstractPreAuthenticatedProcessingFilter
  13. CasAuthenticationFilter
  14. OAuth2LoginAuthenticationFilter
  15. Saml2WebSsoAuthenticationFilter
  16. UsernamePasswordAuthenticationFilter
  17. DefaultLoginPageGeneratingFilter
  18. DefaultLogoutPageGeneratingFilter
  19. ConcurrentSessionFilter
  20. DigestAuthenticationFilter
  21. BearerTokenAuthenticationFilter
  22. BasicAuthenticationFilter
  23. RequestCacheAwareFilter
  24. SecurityContextHolderAwareRequestFilter
  25. JaasApiIntegrationFilter
  26. RememberMeAuthenticationFilter
  27. AnonymousAuthenticationFilter
  28. OAuth2AuthorizationCodeGrantFilter
  29. SessionManagementFilter
  30. ExceptionTranslationFilter  //异常处理过滤器
  31. FilterSecurityInterceptor
  32. SwitchUserFilter

        //这些过滤器的排序是Spring官方提供的,后来Spring可能觉得这样展示的意义不大,删去了这部分内容, 补充了一些从日志查看过滤器加载顺序的说明。(过滤器的加载顺序会在Info日志中打印,以实时加载为准)。

6、Spring Security 如何处理安全异常?

        //首先说,这里就是 Spring Security 的工作原理,重中之重,非常重要,虽然讲的是一个异常过滤器,但是实际上是一个执行流程。

        ExceptionTranslationFilter 允许将 AccessDeniedException 和 AuthenticationException 转换为 HTTP 响应。//两个异常,禁止访问 + 认证异常

        ExceptionTranslationFilter 作为安全过滤器之一,自动插入到 FilterChainProxy 中。

        下图显示了 ExceptionTranslationFilter 与其他组件的关系:

Spring Security 的工作原理/总体架构,Spring Security,spring,spring security

        首先,ExceptionTranslationFilter 调用 FilterChain.doFilter(request, response) 来调用应用程序的剩余部分,这里有两种情况,用户未经过认证以及用户被拒绝访问// Continue ProcessingRequest Normally -> 继续正常处理请求

        如果用户未经过身份验证或者抛出了 AuthenticationException,则启动身份验证

  1. 首先清除 SecurityContextHolder,这个是一个 Spring Security 中的一个核心类。
  2. RequestCache:保存 HttpServletRequest 请求,在身份验证成功后可以使用它重复原始请求。//也可以不保存,那么用户就需要重新去请求
  3. AuthenticationEntryPoint 用于从客户端获取请求凭据。例如,它可能重定向到登录页面或发送 WWW-Authenticate 报文头。//AuthenticationEntryPoint(接口) -> 比如重定向到登录页面,要求登录,执行从客户端获取请求凭据的策略

        //以上这三个类都给出了身份验证的大致流程,流程中给出了这些关键类的使用时机,描述了 Spring Security 的大致框架。

        如果是 AccessDeniedException,则拒绝访问。直接调用 AccessDeniedHandler 来处理拒绝访问。// AccessDeniedHandler(接口),也可以自定义处理策略

        如果应用程序没有抛出 AccessDeniedException AuthenticationException,则ExceptionTranslationFilter 不做任何事情。//这个过滤器只处理这两个异常

        ExceptionTranslationFilter 的伪代码逻辑如下:

try {
	filterChain.doFilter(request, response);
} catch (AccessDeniedException | AuthenticationException ex) { //捕获特定异常
	if (!authenticated || ex instanceof AuthenticationException) {
		startAuthentication(); //启动认证流程
	} else {
		accessDenied(); //决绝策略
	}
}

7、在认证的时候保存用户请求

        当用户请求资源时,如果没有经过身份验证,就需要保存请求信息,当身份验证成功后再重新执行该请求。在 Spring Security 中,通过使用 RequestCache 的实现来保存 HttpServletRequest。//RequestCache是一个接口,请求缓存策略可以有不同的实现

        RequestCacheAwareFilter 和 RequestCache 接口

        HttpServletRequest 保存在 RequestCache 中。当用户成功通过身份验证时,将使用 RequestCache 重新执行原始请求。

        RequestCacheAwareFilter 使用 RequestCache 来保存 HttpServletRequest。默认情况下,使用 HttpSessionRequestCache

        下面的代码演示了如何定制 RequestCache 的实现,该实现用于在参数 continue 存在的情况下检查保存请求的 HttpSession。//这里存储的是一个标记,通过RequestCacheAwareFilter过滤器使用

@Bean
DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
	HttpSessionRequestCache requestCache = new HttpSessionRequestCache();
	requestCache.setMatchingRequestParameterName("continue");
	http
		// ...
		.requestCache((cache) -> cache.requestCache(requestCache));
	return http.build();
}

        如果不希望在会话中存储用户未经身份验证的请求,可以使用 NullRequestCache 实现。//不保存会话信息,直接重定向到登录页

@Bean
SecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
    RequestCache nullRequestCache = new NullRequestCache();
    http
        // ...
        .requestCache((cache) -> cache.requestCache(nullRequestCache));
    return http.build();
}

        至此,全文结束。文章来源地址https://www.toymoban.com/news/detail-602744.html

到了这里,关于Spring Security 的工作原理/总体架构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Security 身份验证的基本类/架构

    目录 1、SecurityContextHolder 核心类 2、SecurityContext 接口 3、Authentication 用户认证信息接口 4、GrantedAuthority 拥有权限接口 5、AuthenticationManager 身份认证管理器接口 6、ProviderManager 身份认证管理器的实现 7、AuthenticationProvider 特定类型的身份验证接口 8、AuthenticationEntryPoint 身份验证

    2024年02月16日
    浏览(38)
  • Spring Security 和 Apache Shiro 登录安全架构选型

    Spring Security和Apache Shiro都是广泛使用的Java安全框架,它们都提供了许多功能来保护应用程序的安全性,包括身份验证、授权、加密、会话管理等。 Spring Security和Apache Shiro都是非常常用的登录安全框架,两者在登录安全架构的选型上各有特点: Spring Security特点: 与Spring框架深度集

    2024年02月14日
    浏览(34)
  • 你对Spring Security使用场景以及底层原理有了解吗?

    Spring Security是一个基于Spring框架的安全性解决方案,提供了全面的身份验证、授权和安全功能。它可以应用于多种场景以确保应用程序的安全性和保护敏感资源。以下是一些常见的Spring Security的使用场景: 用户登录和认证:Spring Security可以处理用户的身份验证,包括用户名密

    2024年02月05日
    浏览(31)
  • 【深入浅出Spring Security(三)】默认登录认证的实现原理

    由默认的 SecurityFilterChain 为例(即表单登录),向服务器请求 /hello 资源Spring Security 的流程分析如下: 请求 /hello 接口,在引入 Spring Security 之后会先经过一系列过滤器(一中请求的是 /test 接口); 在请求到达 FilterSecurityInterceptor 时,发现请求并未认证。请求被拦截下来,并

    2024年02月09日
    浏览(38)
  • 【深入浅出 Spring Security(七)】RememberMe的实现原理详讲

    先看看最简单用法的默认页面效果变化。 SecurityConfig 配置类 测试 TestController 代码 以下是给出的默认的登录页面。 观察页面源代码可以发现,比原先没配置 RememberMe 之前多了个 name 为 remember-me 的 checkbox 选项。 如果我们勾选了它并且登录成功后,当我们关闭掉当前浏览器,

    2024年02月09日
    浏览(38)
  • 【深入浅出 Spring Security(十一)】授权原理分析和持久化URL权限管理

    在 【深入浅出Spring Security(一)】Spring Security的整体架构 中小编解释过授权所用的三大组件,在此再解释说明一下(三大组件具体指:ConfigAttribute、AccessDecisionManager(决策管理器)、AccessDecisionVoter(决策投票器)) ConfigAttribute 在 Spring Security 中,用户请求一个资源(通常是

    2024年02月10日
    浏览(54)
  • 【Spring Security】Spring Security 认证与授权

    在前面的章节中,我们沿用了Spring Security默认的安全机制:仅有一个用户,仅有一种角色。在实际开发中,这自然是无法满足需求的。本章将更加深入地对Spring Security迚行配置,且初步使用授权机制。 3.1 默认数据库模型的认证与授权 3.1.1、资源准备 首先,在controller包下新建

    2024年02月05日
    浏览(54)
  • Spring Security入门教程,springboot整合Spring Security

    Spring Security是Spring官方推荐的认证、授权框架,功能相比Apache Shiro功能更丰富也更强大,但是使用起来更麻烦。 如果使用过Apache Shiro,学习Spring Security会比较简单一点,两种框架有很多相似的地方。 目录 一、准备工作 创建springboot项目 pom.xml application.yml 二、创建相关的类

    2024年02月05日
    浏览(49)
  • Spring Security OAuth2.0(3):Spring Security简单入门

    Spring Security 快速入门。 本章代码已分享至Gitee:https://gitee.com/lengcz/security-spring-security qquad Spring Secutiry 是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。由于它是Spring生态系统的一员,因此它伴随着整个Spring生态系统不断修正、升级,

    2024年02月13日
    浏览(48)
  • 安全框架Spring Security是什么?如何理解Spring Security的权限管理?

    大家好,我是卷心菜。本篇主要讲解Spring Security的基本介绍和架构分析,如果您看完文章有所收获,可以三连支持博主哦~,嘻嘻。 🎁 作者简介: 在校大学生一枚,Java领域新星创作者,Java、Python正在学习中,期待和大家一起学习一起进步~ 💗 个人主页:我是一棵卷心菜的

    2024年02月02日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包