Spring Security 6.1.x 系列(3)—— 基于过滤器的基础原理(二)

四、SecurityFilterChain

Serlvet中,一组Security Filter组成SecurityFilterChainSecurityFilterChain的概念就比较好理解,是Spring Security 提供的过滤器链,用于管理本身所有的过滤器,在上面的流程图中已有说明。

SecurityFilterChain可以被FilterChainProxy用来确定当前请求应该调用哪些Spring Security Filter实例。

在整个流程中, FilterchainProxy 决定应该使用哪个SecurityFilterChain,只有第一个匹配SecurityFilterChain被调用。如果请求的URL不匹配,则继续尝试每个SecurityFilterChain

比如在下图中,如果请求的URL/api/messages/,那么会匹配到右侧上方的 SecurityFilterChain0 ,如果都不匹配,则会调用支持 /*SecurityFilterChainn

在这里插入图片描述

五、Security Filters

Spring Security 中的过滤器是通过 SecurityFilterChain API 插入FilteChainProxy中的,Filter实例的顺序非常重要。

Spring Security 中的过滤器按照如下所示 (后续会详细介绍):

  • ForceEagerSessionCreationFilter
  • ChannelProcessingFilter
  • WebAsyncManagerlntegrationFilterSecurityContextPersistenceFilter
  • HeaderWriterFilter
  • CorsFilter
  • CsrfFilter
  • LogoutFilter
  • OAuth2AuthorizationRequestRedirectFilter
  • Saml2WebSsoAuthenticationRequestFilter
  • X509AuthenticationFilter
  • AbstractPreAuthenticatedProcessingFilter
  • CasAuthenticationFilter
  • OAuth2LoginAuthenticationFilter
  • Saml2WebSsoAuthenticationFilter
  • UsernamePasswordAuthenticationFilter
  • DefaultLoginPageGeneratingFilter
  • DefaultLogoutPageGeneratingFilter
  • ConcurrentSessionFilter
  • DigestAuthenticationFilter
  • BearerTokenAuthenticationFilter
  • BasicAuthenticationFilter
  • RequestCacheAwareFilter
  • SecurityContextHolderAwareRequestFilter
  • JaasApilntegrationFilter
  • RememberMeAuthenticationFilter
  • AnonymousAuthenticationFilter
  • OAuth2AuthorizationCodeGrantFilter
  • SessionManagementFilter
  • ExceptionTranslationFilterFilter
  • SecuritylnterceptorSwitchUserFilter

5.1 打印Security Filter

可通过以下配置:

@EnableWebSecurity(debug = true)

打印请求URL匹配SecurityFilterChain中的Security Filter信息。

5.2 将自定义Filter添加到SecurityFilterChain

大多数情况下,默认Security Filter足以为应用程序的安全性要求。 但是有时您可能希望将自定义Filter添加到SecurityFilterChain中。

一个简单的自定义Filter代码示例:

public class TenantFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String tenantId = request.getHeader("X-Tenant-Id"); 
        boolean hasAccess = isUserAllowed(tenantId); 
        if (hasAccess) {
            filterChain.doFilter(request, response); 
            return;
        }
        throw new AccessDeniedException("Access denied"); 
    }
}

上面的示例代码执行以下操作:

  • 从请求头中获取租户ID。
  • 检查当前用户是否有权访问租户ID。
  • 如果用户具有访问权限,则调用链中的其余筛选器。
  • 如果用户没有访问权限,则抛出AccessDeniedException

将其添加到SecurityFilterChain代码示例:

@Configuration
@EnableWebSecurity(debug = true)
public class SecurityConfig {

    @Bean
    @Order
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
            throws Exception {
        http.formLogin(Customizer.withDefaults());
        http.passwordManagement(Customizer.withDefaults());
        // 将过滤器添加在AuthorizationFilter之前
        http.addFilterBefore(new TenantFilter(), AuthorizationFilter.class);
        return http.build();
    }
}

Filter使用@Component注解声明为 Spring Bean 时要特别注意。因为 Spring Boot会自动将其注册到容器中。 这可能会导致过滤器被调用两次,一次由容器调用一次由 Spring Security 调用,并且顺序不同。

如果您仍然想将将Filter声明为Spring bean以利用依赖注入,并避免重复调用,您可以通过FilterRegistrationBean并将其Enabled属性设置为false 来实现。

@Bean
public FilterRegistrationBean<TenantFilter> tenantFilterRegistration(TenantFilter filter) {
    FilterRegistrationBean<TenantFilter> registration = new FilterRegistrationBean<>(filter);
    registration.setEnabled(false);
    return registration;
}

六、处理安全异常

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

ExceptionTranslationFilter作为Security Filter之一插入到 FilterChainProxy 中。

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

在这里插入图片描述
①首先,调用应用程序的其余部分,正常继续处理请求。ExceptionTranslationFilterFilterChain.doFilter(request, response)

②如果用户未通过身份验证,或者是开启身份验证,抛出AuthenticationException异常:

  • SecurityContextHolder被清除。
  • 请求缓存,以便在身份验证成功后可用于重播原始请求。HttpServletRequest
  • 用于从客户端请求凭据。 例如,它可能会重定向到登录页面或发送请求头。AuthenticationEntryPointWWW-Authenticate

③否则拒绝访问, 调用AccessDeniedHandler处理被拒绝的访问。

七、身份验证间请求缓存

处理安全异常中所示,当请求没有身份验证并且针对需要身份验证的资源时,需要保存身份验证资源的请求缓存,以便在身份验证成功后重新请求。

Spring Security中,这是通过使用RequestCache实现保存来完成的。

7.1 请求缓存

RequestCacheAwareFilter用于保存RequestCache。当用户成功进行身份验证时,将用于重播原始请求。

一个简单的仅当参数存在时才检查已保存的请求代码示例:

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

7.2 阻止保存请求

您可能希望不要在会话中存储用户未经身份验证的请求或您始终希望将用户重定向到主页,而不是他们在登录前尝试访问的页面。为此可以使用NullRequestCache 实现。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/111020.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2023年软件测试工具总结 —— 单元测试工具

在应用程序中&#xff0c;单元是具有一个或多个输入和单个输出的软件中最小可测试部分。单元测试是一种测试软件代码单元的方法&#xff0c;通常包括一个或两个输入&#xff0c;产生一个输出。单元测试主要关注独立模块的功能正确性&#xff0c;目的是确保每个单元都按照预期的…

360加固APP后启动崩溃—注意加固前后签名是否一致

如下截图所示&#xff0c;我今天就是遇到了这个问题&#xff0c;这个问题是比较好解决&#xff0c;但如果官网有显眼指引说明会不会对开发者更友好些呢&#xff1f; 首先我们给360的加固包是带有自己的签名的&#xff0c;然后经360加固过后&#xff08;免费的加固服务&#xf…

软件测试简历没有邀约,为什么?8类细节通通告诉你(附赠高薪简历)

求职不顺&#xff0c;没有邀约&#xff0c;大概率是你的简历出现了问题。 本篇文章列出高薪简历应该注意的细节&#xff0c;合计36处&#xff0c;涉及简历的八大组成部分。 现在就讲&#xff1a; 一、简历样式要求&#xff08;3点要求&#xff09; 1、简历格式&#xff0c;…

Ansible的安装及部署

目录 一、ansible的简介 二、ansible的安装 1、下载epel仓库 2、安装ansible 3、全局测试 4、构建Anisble清单 三、Ansible配置文件参数详解 1. 配置文件的分类与优先级 2. 常用配置参数 四、构建用户级Ansible操作环境 一、ansible的简介 1、ansible是新出现的自…

arcpy.describe

描述 根据输入的数据&#xff0c;返回输入数据的属性 arcpy.da.Describe与arcpy.Describe返回的数据是一样的但是返回的的类型不一样&#xff0c;arcpy.da.Describe返回的是字典&#xff0c;arcpy.Describe返回的是string 如果要访问数据对象不存在的属性&#xff0c;将返回…

史上最短苹果发布会;三星、LG、高通联手进军 XR 市场丨 RTE 开发者日报 Vol.74

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

Bayes决策:身高与体重特征进行性别分类

代码与文件请从这里下载&#xff1a;Auorui/Pattern-recognition-programming: 模式识别编程 (github.com) 简述 分别依照身高、体重数据作为特征&#xff0c;在正态分布假设下利用最大似然法估计分布密度参数&#xff0c;建立最小错误率Bayes分类器&#xff0c;写出得到的决…

预安装win11的电脑怎么退回正版win10?

对于新购的笔记本 通常来讲预装的系统是全新安装的&#xff0c;是没有之前Windows10系统文件的&#xff0c;无法回退。 可以打开设置-----系统----恢复-----看下是否有该选项。 ------------------------------------------------------------------------------- 若是在上述…

第五章 I/O管理 七、设备的分配与回收

目录 一、设备分配时应该考虑的因素 1、设备的固有属性 2、设备分配算法 3、设备分配中的安全性 &#xff08;1&#xff09;安全分配方式: 优点: 缺点: &#xff08;2&#xff09;不安全分配方式: 优点: 缺点: 4、静态分配 5、动态分配 二、设备分配管理中的数据结…

深入探究ASEMI肖特基二极管MBR60100PT的材质

编辑-Z 在电子零件领域中&#xff0c;肖特基二极管MBR60100PT因其出色的性能和广泛的应用而显得尤为关键。理解其材质不仅有助于我们深入理解其运作原理&#xff0c;也有助于我们做出更合适的电子设计。那么&#xff0c;肖特基二极管MBR60100PT是什么材质呢? 首先&#xff0c…

3D模型怎么贴法线贴图?

1、法线贴图的原理&#xff1f; 法线贴图&#xff08;normal mapping&#xff09;是一种计算机图形技术&#xff0c;用于在低多边形模型上模拟高多边形模型的细节效果。它通过在纹理坐标上存储和应用法线向量的信息来实现。 法线贴图的原理基于光照模型。在渲染过程中&#x…

CentOS 安装 tomcat 并设置 开机自启动

CentOS 安装 tomcat 并设置 开机自启动 下载jdk和tomcat curl https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.tar.gz curl https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.15/bin/apache-tomcat-10.1.15.tar.gz解压jdk和tomcat并修改目录名称 tar -z…

【机器学习】二、决策树

目录 一、决策树定义&#xff1a; 二、决策树特征选择 2.1 特征选择问题 2.2 信息增益 2.2.1 熵 2.2.2 信息增益 三、决策树的生成 3.1 ID3算法 3.1.1理论推导 3.1.2代码实现 3.2 C4.5 算法 3.2.1理论推导 ​ 3.2.2代码实现 四、决策树的剪枝 4.1 原理 4.2 算法思路&#xff1a…

Chrome如何解决http自动转为https问题

开发中总遇到http被浏览器转为https导致无法访问404 具体配置如下&#xff1a; 就能正常访问你的http不安全地址

一篇文章让你弄懂Java中的方法

目录 1. 方法概念及使用 1.1 什么是方法(method) 1.2 方法定义 1.3 方法调用的执行过程 1.4 实参和形参的关系 1.5 没有返回值的方法 2. 方法重载 2.1 为什么需要方法重载 2.2 方法重载概念 2.3 方法签名 1. 方法概念及使用 1.1 什么是方法(method) 方法就是一…

SkyWalking官方文档-1-概述

概述 SkyWalking是一个开源的可观测平台&#xff0c;用于收集&#xff0c;分析&#xff0c;聚合&#xff0c;以及可视化处理来自服务和云原生框架的数据。SkyWalking提供了一种简单的方法来维护分布式系统的清晰视图&#xff0c;即使是跨云。 它是一种现代APM&#xff0c;专门…

uniapp 模仿 Android的Menu菜单栏

下面这张图就是我们要模拟的菜单功能 一、模拟的逻辑 1. 我们使用uni-popup组件&#xff08;记得要用hbuilder X导入该组件&#xff09;uni-app官网 2. 将组件内的菜单自定义样式 二、uniapp代码 写法vue3 <template><view><uni-popup ref"showMenu"…

Mgeo:multi-modalgeographic language model pre-training

文章目录 question5.1 Geographic Encoder5.1.1 Encoding5.1.2 question 给定query&#xff0c;如何选取周边n个地理实体。&#xff08;按照距离远近&#xff09; 训练过程如何进行。 5.1 Geographic Encoder 如果没有 GC&#xff0c;仅有地理定位是毫无意义的。地理编码器将…

腾讯待办关停后怎么恢复使用?可自动设置提醒时间的待办工具

你是否曾经有过这样的经历&#xff1a;突然想到一个重要的任务&#xff0c;但却忘记立即记录下来&#xff0c;导致事后无法及时完成&#xff1f;我们的日常生活充满了琐碎的任务&#xff0c;而记录待办事项并设置提醒时间&#xff0c;可以帮助我们更好地组织和管理时间。 记录…