SpringSecuirty源码学习(四)

    xiaoxiao2021-03-25  116

    前言

    总结创建WebSecuirty的创建过程,及其构建过程。有和前面重复的地方,不管了…

    1. 用户自定义的配置类

    @EnableWebSecurity @ComponentScan("fn.wd.security") public class SpringSecurityConfiger extends WebSecurityConfigurerAdapter { ... }

    2. @EnableWebSecurity

    @Import({ WebSecurityConfiguration.class, ObjectPostProcessorConfiguration.class, SpringWebMvcImportSelector.class }) @EnableGlobalAuthentication @Configuration public @interface EnableWebSecurity { ... }

    3. WebSecurityConfiguration中创建WebSecurity

    @Autowired(required = false) public void setFilterChainProxySecurityConfigurer( //参数一:注入被@EnableWebSecurity注入导入的后置处理器 ObjectPostProcessor<Object> objectPostProcessor, //参数二:注入spring web容器中所有的WebSecurityConfigurer List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers) { //1.创建WebSecurity,传递objectPostProcessor,是为了当这个构建器构建对象完成后,可以给这个对象进行后置处理 //2.后置处理WebSecurity //3.PS:后置处理的功能是:使容器外的对象享受像spring容器内的bean一样的待遇 webSecurity = objectPostProcessor .postProcess(new WebSecurity(objectPostProcessor)); if (debugEnabled != null) { webSecurity.debug(debugEnabled); } //将配置WebSecurity的配置器排序,这里通常就是我们自定义的那个SecurityConfigurerAdapter Collections.sort(webSecurityConfigurers, AnnotationAwareOrderComparator.INSTANCE); //如果有多个配置器,配置顺序不能是一样的,否则通不过 Integer previousOrder = null; Object previousConfig = null; for (SecurityConfigurer<Filter, WebSecurity> config : webSecurityConfigurers) { Integer order = AnnotationAwareOrderComparator.lookupOrder(config); if (previousOrder != null && previousOrder.equals(order)) { throw new IllegalStateException( "@Order on WebSecurityConfigurers must be unique. Order of " + order + " was already used on " + previousConfig + ", so it cannot be used on " + config + " too."); } previousOrder = order; previousConfig = config; } //让我们自定义的SecurityConfigurerAdapter,应用到new出来的这个WebSecurity for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) { webSecurity.apply(webSecurityConfigurer); } //将用到的配置器放到属性中,以提示:已经对WebSecurity进行配置了 this.webSecurityConfigurers = webSecurityConfigurers; }

    可以看到,webSecurityConfigurers中就是我们自定义的那一个:

    4. WebSecurityConfiguration中触发WebSecurity的构建过程

    //构建的bean的名字叫做:springSecurityFilterChain @Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME) public Filter springSecurityFilterChain() throws Exception { //看webSecurityConfigurers是不是空,以判断是否对WebSecurity进行了配置 boolean hasConfigurers = webSecurityConfigurers != null && !webSecurityConfigurers.isEmpty(); //如果没有配置(即:用户没有自定义WebSecurityConfigurerAdapter),那么框架会给一个空实现,所有配置功能都使用WebSecurityConfigurerAdapter中默认的 if (!hasConfigurers) { WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor .postProcess(new WebSecurityConfigurerAdapter() { }); webSecurity.apply(adapter); } //触发FilterChainProxy的构建过程 return webSecurity.build(); }

    5.AbstractConfiguredSecurityBuilder定义构建模版

    AbstractConfiguredSecurityBuilder是WebSecurity的父类,定义了doBuild()方法的执行模版。

    //build()->doBuild();做了些什么呢?前文有提到过哦~ protected final O doBuild() throws Exception { //针对WebSecurity.这里的configurers指的就是我们自定义的那个WebSecurityConfigurer synchronized (configurers) { buildState = BuildState.INITIALIZING; beforeInit(); //init()前面也说过,迭代所有的configurer,调用它们的init(builder) init(); buildState = BuildState.CONFIGURING; beforeConfigure(); //configure()前面也说过,迭代所有的configurer,调用它们的configure(builder) configure(); buildState = BuildState.BUILDING; //performBuild()需要子类实现,WebSecurity中是怎么实现的呢? O result = performBuild(); buildState = BuildState.BUILT; return result; } }

    WebSecurityConfigurerAdapter完成模版方法中的init()

    这里触发了HttpSecurity的创建(后面详细讨论),并将其设置到WebSecurity中。

    public void init(final WebSecurity web) throws Exception { final HttpSecurity http = getHttp(); //将HttpSecurity添加到WebSecurity的securityFilterChainBuilders属性中 web.addSecurityFilterChainBuilder(http).postBuildAction(new Runnable() { public void run() { FilterSecurityInterceptor securityInterceptor = http .getSharedObject(FilterSecurityInterceptor.class); web.securityInterceptor(securityInterceptor); } }); }

    SpringSecurityConfiger完成模版方法中的configurer()

    注意:这个类并不是框架的,是需要用户自定义实现的。WebSecurityConfigurerAdapter中configurer()是空实现的,由子类(用户自定义的)去完成实现。一个例子:

    @EnableWebSecurity @ComponentScan("fn.wd.security") public class SpringSecurityConfiger extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) throws Exception { /* * web.ignoring()返回的是ignoredRequestRegistry,最终将忽略的请求 * 添加到WebSecurity中的ignoredRequests属性中。 */ web.ignoring().antMatchers("/static/**"); web.ignoring().antMatchers("/favicon.ico"); web.ignoring().antMatchers("/resources/**"); } }

    它的功能还记得吗?前文有提到哦~~

    WebSecurity完成模版方法中的performBuild()

    有关异常和校验等的代码被我删掉了,只保留了核心的,请自行查看源码。 @Override protected Filter performBuild() throws Exception { //ignoredRequests.size():是获取忽略的请求个数 //securityFilterChainBuilders.size():是获取“过滤器链的配置器”的个数 int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size(); //链,集合 List<SecurityFilterChain> securityFilterChains = new ArrayList<SecurityFilterChain>(chainSize); //给需要忽略的请求分别创建没有一个过滤器的链 for (RequestMatcher ignoredRequest : ignoredRequests) { securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest)); } //使用“过滤器链的配置器”创建过滤器链 for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) { //触发了HttpSecurity的构建过程(后面详细讨论) securityFilterChains.add(securityFilterChainBuilder.build()); } //创建过滤器链的代理,将所有的过滤器链都封装进去 FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains); if (httpFirewall != null) { filterChainProxy.setFirewall(httpFirewall); } filterChainProxy.afterPropertiesSet(); Filter result = filterChainProxy; postBuildAction.run(); //返回这个过滤器链的代理 return result; }
    转载请注明原文地址: https://ju.6miu.com/read-18328.html

    最新回复(0)