SpringBoot--Spring Security(一)

SpringBoot–Spring Security(一)

一、概述

源码基于SpringBoot 2.7.xx版本

官网:https://spring.io/projects/spring-security

1.1 自动装配概览

  • SecurityAutoConfiguration
    • DefaultAuthenticationEventPublisher
    • SpringBootWebSecurityConfiguration
      • @EnableWebSecurity
        • WebSecurityConfiguration
        • SpringWebMvcImportSelector
        • OAuth2ImportSelector
        • HttpSecurityConfiguration
        • @EnableGlobalAuthentication
          • AuthenticationConfiguration
    • SecurityDataConfiguration
  • UserDetailsServiceAutoConfiguration
    • InMemoryUserDetailsManager
  • SecurityFilterAutoConfiguration
    • DelegatingFilterProxyRegistrationBean
  • @EnableMethodSecurity
    • MethodSecuritySelector
      • PrePostMethodSecurityConfiguration
      • SecuredMethodSecurityConfiguration
      • Jsr250MethodSecurityConfiguration

二、自动装配详解

2.1 SecurityAutoConfiguration

  1. 注册 DefaultAuthenticationEventPublisher;
  2. 导入另外两个安全配置类SpringBootWebSecurityConfiguration、SecurityDataConfiguration

2.2 SpringBootWebSecurityConfiguration


@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {
   

    @Configuration(proxyBeanMethods = false)
    // 条件一 classpath中存在 SecurityFilterChain.class, HttpSecurity.class
    // 条件二 没有自定义 WebSecurityConfigurerAdapter.class, SecurityFilterChain.class
    @ConditionalOnDefaultWebSecurity
    static class SecurityFilterChainConfiguration {
   
        @Bean
        @Order(SecurityProperties.BASIC_AUTH_ORDER)
        SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
   
            // 默认情况下对所有请求进行权限控制
            http.authorizeRequests().anyRequest().authenticated();
            http.formLogin();
            http.httpBasic();
            return http.build();
        }
    }

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)
    @ConditionalOnClass(EnableWebSecurity.class)
    @EnableWebSecurity
    static class WebSecurityEnablerConfiguration {
   

    }
}

2.2.1 SecurityFilterChain

默认的SecurityFilterChain,对所有请求进行权限控制,默认配置引入条件

  1. classpath中存在 SecurityFilterChain.class, HttpSecurity.class
  2. 没有自定义 WebSecurityConfigurerAdapter.class, SecurityFilterChain.class

2.2.2 @EnableWebSecurity

导入了如下4个类:

  1. WebSecurityConfiguration
  2. SpringWebMvcImportSelector
  3. OAuth2ImportSelector
  4. HttpSecurityConfiguration
2.2.2.1 WebSecurityConfiguration

WebSecurity配置类,创建一个FilterChainProxy bean来对用户请求进行安全过滤,这个FilterChainProxy bean的
名称为springSecurityFilterChain,它也是一个Filter,最终会被作为DelegatingFilterProxy代理的对象放入Spring容器中。

/**
 *  WebSecurity 配置类 : 
 *  1. 使用一个 WebSecurity 对象基于安全配置创建一个 FilterChainProxy 对象来对用户请求进行安全过滤。 
 *  2. 也会暴露一些必要的 bean。
 *  3. 如何定制 Spring security 的web 安全,也就是 WebSecurity 对象
 *     3.1 提供一个配置类,实现了接口 WebSecurityConfigurer
 *     3.2 或者创建一个WebSecurityCustomizer对象
 *    该配置类的配置会在使用 @EnableWebSecurity 时应用到系统。
 */
@Configuration(proxyBeanMethods = false)
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
   

    private WebSecurity webSecurity;
    // 是否启用了调试模式,来自注解 @EnableWebSecurity 的属性 debug,缺省值 false
    private Boolean debugEnabled;

    private List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers;

    private List<SecurityFilterChain> securityFilterChains = Collections.emptyList();

    private List<WebSecurityCustomizer> webSecurityCustomizers = Collections.emptyList();

    private ClassLoader beanClassLoader;

    @Autowired(required = false)
    private ObjectPostProcessor<Object> objectObjectPostProcessor;

    @Bean
    public static DelegatingApplicationListener delegatingApplicationListener() {
   
        return new DelegatingApplicationListener();
    }

    // 定义一个表达式处理器bean,缺省为一个 DefaultWebSecurityExpressionHandler,
    //  仅在 bean springSecurityFilterChain 实例化之后才能实例化
    @Bean
    @DependsOn(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
    public SecurityExpressionHandler<FilterInvocation> webSecurityExpressionHandler() {
   
        return this.webSecurity.getExpressionHandler();
    }

    // 定义 FilterChainProxy , 名字为 springSecurityFilterChain
    @Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
    public Filter springSecurityFilterChain() throws Exception {
   
        boolean hasConfigurers = this.webSecurityConfigurers != null && !this.webSecurityConfigurers.isEmpty();
        boolean hasFilterChain = !this.securityFilterChains.isEmpty();
        Assert.state(!(hasConfigurers && hasFilterChain),
                "Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one.");
        if (!hasConfigurers && !hasFilterChain) {
   
            // 如果没有 webSecurityConfigurer, 则提供一个却省的
            WebSecurityConfigurerAdapter adapter = this.objectObjectPostProcessor
                    .postProcess(new WebSecurityConfigurerAdapter() {
   
                    });
            this.webSecurity.apply(adapter);
        }
        for (SecurityFilterChain securityFilterChain : this.securityFilterChains) {
   
            this.webSecurity.addSecurityFilterChainBuilder(() -> securityFilterChain);
            for (Filter filter : securityFilterChain.getFilters()) {
   
                if (filter instanceof FilterSecurityInterceptor) {
   
                    this.webSecurity.securityInterceptor((FilterSecurityInterceptor) filter);
                    break;
                }
            }
        }
        for (WebSecurityCustomizer customizer : this.webSecurityCustomizers) {
   
            customizer.customize(this.webSecurity);
        }
        // 根据配置 webSecurityConfigurers或者缺省 WebSecurityConfigurerAdapter 构建 
        // FilterChainProxy 并返回,这是最终加入到Servlet容器的Filter chain 。
        return this.webSecurity.build();
    }

    // 定义一个bean,是web调用权限评估器,用于判断一个用户是否可以访问某个URL,
    // 对于 JSP tag 支持必要。仅在bean springSecurityFilterChain 被定义时才生效。
    @Bean
    @DependsOn(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
    public WebInvocationPrivilegeEvaluator privilegeEvaluator() {
   
        return this.webSecurity.getPrivilegeEvaluator();
    }

    // 注入webSecurityConfigurers
    @Autowired(required = false)
    public void setFilterChainProxySecurityConfigurer(ObjectPostProcessor<Object> objectPostProcessor,
                                                      ConfigurableListableBeanFactory beanFactory) throws Exception {
   
        this.webSecurity = objectPostProcessor.postProcess(new WebSecurity(objectPostProcessor));
        
  • 47
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fanderboy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值