栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

揭开Spring Security 责任链秘密

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

揭开Spring Security 责任链秘密

前言

Spring Security是一个优秀的安全管理框架,同时他很多地方支持可定制化。基于Spring Security,我们就可以做出供自己业务场景下的安全管理需求,例如在SaaS服务下的多租户权限控制。而Spring Security中最重要的实现方式,最重要的设计模式,那便非责任链模式莫属了。

配置初始化

在配置初始化前,都需要有一个机制来触发配置的初始化,道理很简单,因为我们不是所有场景下都需要用到Spring Security,只是在我们需要用到这个框架的时候,才需要去触发他。Spring Security对于这个的实现方式其实和大部分的框架都一样,便是使用注解的方式。

Spring Security中使用来@EnableWebSecurity来触发配置的初始化,那为什么使用了这个注解就可以触发配置相关的代码运行呢?

里面用到的方式就是使用了@import注解,使用了这个注解,Spring就会把里面的两个类加载到Spring容器中,供Spring容器的调配。

这时候大家可能会有疑惑,我们平时不是使用@Autowired,@Resource来导入类的么,那是因为我们导入的是我们自己编写的类,一般是通过@ComponentScan(basePackages = {"XXX"})来扫描到对应的包,在分析对应的包内的类中是否有@Autowired,@Resource这些注解,有这些注解就将这个类加载到容器中。但是框架中的类目录地址是多变的,我们可不能通过@ComponentScan(basePackages = {"XXX"})这种方式来获取到对应类信息,所以一般使用注解方式,在注解中使用@import注解将对应的类加在到容器中。而且这个使用@import往往是配置类,也就是类上一般会加上@Configuration,在类中就可以使用@Bean来加载对应的bean到容器中了。

配置类的获取


配置类的获取是在WebSecurityConfiguration中的setFilterChainProxySecurityConfigurer类中,这里展示了@Value的特殊用法,就是里面可以填写类的函数来获取对应的值,这个值就是对应的配置类。并且还创建了webSecurity类,这个类可以用来配置类的执行,并最终生成springSecurityFilterChain,这个就是Spring Security 的责任链,终于看到标题对应的信息了有木有~

进入到这个函数中,可以看到获取到的就是在Spring容器中查找所有WebSecurityConfigurer的实现类,但是配置类一般都有很多通用的方法,所以Spring Security创建一个适配类来配置不同的配置类实现,这个类是WebSecurityConfigurerAdapter,因此我们如果想要实现自己的配置类,只需要自己实现WebSecurityConfigurerAdapter基类即可,在Oauth2中便是使用了这种方式创建了ResourceServerConfiguration等配置类。

责任链的生成

在回归回来,在使用@import注解导入的配置类中存在这个bean,这个bean中webSecurity.build()函数就是配置的开启函数。其中webSecurity的父类是AbstractConfiguredSecurityBuilder,在配置类执行的过程中在这个类上执行了模板模式,可以看到

在执行上面模板函数是,这里有一个很好的设计思路

例如我们想要通过遍历来查找一个公司有多少人,此时有一个基类函数AbstractClass,其中的query()是一个虚函数,对于公司,不能直接遍历里面的职工,但可以遍历公司下一个部门的职工,这时我们就可以这样实现,创建两个类,Staff和Department类都实现了基类

Class Department {
	private List staffs;
	private Integer staffNum;

	@Overide
	public void query() {
		foreach(Staff staff: staffs) {
			stafff.query(staffNum);
		}
	}
}

Class Staff {
	@Overide
	public void query(Integer staffNum) {
		staffNum++;
	}
}

这样做的好处很明显,代码非常的好理解他的作用,并且实现起来也非常的简洁。

那为啥我要特意说一下这种方式,原因就是AbstractConfiguredSecurityBuilder中也是使用了这种方式,不要告诉我AbstractConfiguredSecurityBuilder类已经不知道是啥了哦,他就是WebSecurity的父类,还是不知道的朋友可以往上再翻翻。


最后webSecurity类的build()函数返回结果可以得到List,这个就是过滤器链,但是如果我们手动遍历这个过滤器链,每一个调用其中的filter()函数的话,体验感和设计上也并不是太好,Spring Security中创建了FilterChainProxy类,这个类属性上有List,并提供一个filter功能,提供可以根据请求来获取不同的过滤器,来执行过滤。

对应代码如上,非常简单,我就不进行扩展讲解了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/458582.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号