Spring Security 中的执行原理流程分析

1.简介

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

2.认证授权分析

用户在进行资源访问时,要求系统要对用户进行权限控制,其具体流程如图所示:

3.SpringSecurity认证授权分析

基于Spring Security提供的过滤链,对Spring Security如何完成认证和授权的过程进行分析。

3.1 Servlet技术体系中的过滤链

我们先来看一下JAVA WEB应用中的Servlet过滤链(FilterChain),也是请求响应处理链,这个过滤链中包含Filter和Servlet对象。如图所示:

当客户端向Web服务器(例如Tomcat)发送请求时,Web服务器会为指定的URL请求创建一个过滤链,然后通过这个过滤链中的Servlet和Filter对象处理请求。Filter可在这个执行链中对请求进行预处理,也可以基于业务阻断这个请求继续传递。Servlet主要负责对请求进行分发,例如请求交给url对应的后端处理器进行处理。在我们熟知的Spring MVC 应用中,这个Servlet对象是DispatcherServlet。

public void doFilter(ServletRequest request,          ServletResponse response, FilterChain chain) {  // do something before the rest of the application chain.doFilter(request, response); // invoke the rest of the application// do something after the rest of the application}

3.2 DelegatingFilterProxy

DelegatingFilterProxy是Spring提供的一个Filter接口的实现,目的是在Servlet容器(例如tomcat)和Spring容器(例如ApplicationContext)之间建立一座桥。Servlet 容器允许按照它的规范进行Filter对象的注册,但是它察觉不到Spring中定义的Bean对象。

DelegatingFilterProxy 可以按照Servlet容器规范注册到Servlet容器的过滤链中,然后把工作委托给Spring容器中的Filter Bean对象。如图所示:

DelegatingFilterProxy 对象可以从Spring容器中查找这些Filter类型的Bean对象,然后调用执行这些对象。我们可以看一段代码,例如:

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);}

DelegatingFilterProxy在查找Filter类型的Bean实例时,还可采用一定的延迟机制。这一点非常重要,因为Servlet容器默认会在启动前,注册所有的Filter实例。然而,Spring 使用ContextLoaderListener对象负责加载Spring容器中的Bean,但前提条件是要先完成这些Bean的注册。

3.3 FilterChainProxy

FilterChainProxy对象是Spring Security安全框架提供的一个特殊的过滤器,由DelegatingFilterProxy对象装配。这个过滤器通过SecurityFilterChain对象将一些任务委派给Spring容器中的其它过滤器Bean对象。如图所示:

3.4 SecurityFilterChain


SecurityFilterChain包含很多认证授权过滤器,通过这些过滤器处理客户端请求。如图所示: 

SecurityFilterChain 过滤器链中的所有Security Filters对象都是Bean对象,它们通过FilterChainProxy对象进行注册。同时FilterChainProxy对象还可以决定应该由哪个SecurityFilterChain对象去处理请求,如图所示:

3.5 AbstractAuthenticationProcessingFilter

此对象主要用于处理用户的认证请求,如图所示:

用户提交认证请求时, 此对象会基于认证请求创建Authentication对象,基于此对象封装需要认证的用户信息。然后再将这个对象交给AuthenticationManager进行认证。

3.6 表单方式的认证流程分析

用户去访问服务器中的私有资源时,假如过滤器链中的FilterSecurityInterceptor对象检测到用户还没有认证,则会抛出一个访问被拒绝的异常。这个异常对象可通过ExceptionTranslationFilter对象处理,发起一个重定向请求(/login),然后客户端基于get请求去访问/login资源,服务端返回一个登陆页面。如图:

客户端呈现登陆页面后,用户在登陆页面,提交用户名和密码信息,执行认证操作即可。用户在登陆表单中填写用户名和密码,然后点击登陆按钮提交用户信息,此时SpringSecurity安全框架底层会通过UsernamePasswordAuthenticationFilter对象对用户密码进行认证,如图所示:

UsernamePasswordAuthenticationFilter对象会基于用户提交账号信息创建一个UsernamePasswordAuthenticationToken对象(Authentication类型),然后将此对象交给AuthenticationManager对象(认证管理器)进行认证。

3.7 HTTP请求授权过程分析

用户在进行资源访问时,SpringSecurity会基于 FilterSecurityInterceptor对象对请求进行拦截,然后检测当前请求中的用户是否已经认证,是否有权限访问这个资源。如图所示:

FilterSecurityInterceptor对象拦截到用户请求后会从SecurityContextHolder对象中获取认证对象,然后创建FilterInvocation对象,并通过此对象获取一些配置属性,最后通过AccessDecisionManager对象检查用户是否有权限访问资源,假如有权限,则放行用户对资源的访问。假如没有权限,则抛出AccessDeniedException异常。

3.8 ExceptionTranslationFilter 

ExceptionTranslationFilter过滤器执行时会对异常进行捕获,并从异常堆中提取SpringSecurityException异常对象,然后基于具体的异常类型,调用不同的异常处理器对象进行处理。如图所示:

图中的Security Exception异常类型假如是AuthenticationException类型,可以调用AutenticationEntryPoint对象处理异常。假如是AccessDeniedException类型,则可以调用AccessDeniedHandler对象处理异常。

4.总结:

通过对Spring Security 框架中的过滤链分析,介绍了此框架完成用户身份认证,授权,异常处理的过程。比方说通过UsernamePasswordAuthenticationFilter 过滤器拦截客户端提交的登录表单请求,并基于请求中的信息进行用户身份认证。然后通过FilterSecurityInterceptor 来判断当前请求是否有权限访问对应的资源。如果没有认证或访问受限会抛出相关异常,并由 ExceptionTranslationFilter 过滤器进行捕获和处理。

参考

https://docs.spring.io/spring-security/reference/servlet/index.html

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security原理执行流程可以大致分为以下几步骤: 1. 请求到达应用程序时,先经过Spring Security的过滤链。这个过滤链是由一系列的过滤器组成的,每个过滤器负责处理不同的安全任务。 2. 过滤器链的第一个过滤器是SecurityContextPersistenceFilter。它的主要作用是从Session获取SecurityContext,并将其绑定到当前的线程上下文。 3. 接下来是UsernamePasswordAuthenticationFilter过滤器,它用于处理基于用户名和密码的身份验证请求。它会检查请求是否包含了用户名和密码,并将其封装成一个Authentication对象。 4. 然后,Authentication对象将传递给AuthenticationManager进行身份验证。AuthenticationManager是Spring Security的身份验证核心,它负责验证用户的身份。 5. 在身份验证过程,通过ProviderManager委托给配置的AuthenticationProvider来完成具体的身份验证逻辑。AuthenticationProvider是一个接口,可以由开发人员实现,用于根据具体的身份验证策略来验证用户。 6. 如果身份验证成功,则AuthenticationManager会返回一个已经填充了用户权限信息的Authentication对象。 7. 然后,这个已认证的Authentication对象将传递给AccessDecisionManager进行授权。AccessDecisionManager是Spring Security的授权核心,它负责根据用户的角色和权限决定是否允许访问受保护的资源。 8. 在授权过程,通过AccessDecisionManager委托给配置的AccessDecisionVoter来进行实际的授权决策。AccessDecisionVoter是一个接口,可以由开发人员实现,用于根据具体的授权策略来决定用户是否有权限访问资源。 9. 最后,如果用户被授权访问资源,则请求将继续处理。否则,将返回相应的错误信息或跳转到相应的错误页面。 需要注意的是,上述流程只是Spring Security的基本流程,具体的执行流程还会根据配置和自定义实现而有所不同。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Spring Security 执行原理流程分析](https://blog.csdn.net/weixin_63835553/article/details/122750865)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [spring security执行原理流程](https://blog.csdn.net/chyanwu68/article/details/115191428)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值