SpringSecurity灵魂剖析

SpringSecurity原理剖析

一.前言

​ 在SpringBoot大行其道的时代里,安全认证也被加入Spring家族中。SpringSecurity和Spring做了很好的集成,也是倍受欢迎。但是在使用SpringSecurity的时候会很苦恼,只是按照网上的帖子配置一下,但是具体的运行流程与原理很多人却是很蒙蔽。具体的原理也是一知半解的,源码看不懂,很多人在学习的道路上走着走着就不见了… 本人也苦于SpringSecurity原理的困扰很久,经过了九九八十一天的刻苦钻研,得到一些领悟,特此记录,以供日后翻阅。

​ 目录中的前三章节在网上都可以随处搜索的到,本文重点讲解配置之外的深层次的原理。

一. 配置Spring Security的依赖

​ 首先搭建一个SpringBoot项目,在该项目中引入Spring Security的依赖包,不多说,直接上pom的依赖配置

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- jwt token令牌 -->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.8.3</version>
        </dependency>

        <!-- Spring security 安全认证 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

二.继承WebSecurityConfigurerAdapter 配置安全认证

@Component
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; // JWT拦截器
    @Autowired
    private AjaxAuthenticationEntryPointHandler entryPointHandler;//未登陆handler
    @Autowired
    private AjaxAccessDeniedHandler accessDeniedHandler; //无权限访问handler
    @Autowired
    private AjaxAuthenticationFailureHandler failureHandler; //登陆失败handler
    @Autowired
    private AjaxLogoutSuccessHandler logoutHandler;//退出handler
    @Autowired
    private AjaxAuthenticationSuccessHandler successHandler;//登陆成功handler
    @Autowired
    private UserDetailsServerImpl detailsServer;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private SecurityProperties securityProperties;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(detailsServer).passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(securityProperties.getUris().toArray(new String[0]));
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .httpBasic().authenticationEntryPoint(entryPointHandler)
                .and()
                .formLogin()
                .successHandler(successHandler)
                .failureHandler(failureHandler)
                .and()
                .logout()
                .logoutSuccessHandler(logoutHandler)
                .permitAll()
                .and()
                .authorizeRequests()
                .anyRequest()
                .access("@RBACAuthorityManager.hasPermission(request,authentication)")
                .and()
                .exceptionHandling().accessDeniedHandler(accessDeniedHandler);
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        //http.userDetailsService(detailsServer);
    }

    public String encoder(String pwd) {
        return passwordEncoder.encode(pwd);
    }
}

三. Filter过滤器的加载

​ 在以上的配置中,整个核心的安全配置都是通过HttpSecurity来完成的,究竟HttpSecurity为我们做了些什么呢?请看下方:

在这里插入图片描述

​ HttpSecurity 这个对象中维护了一个Filter数组,Spring在启动的时候会将那些配置的Filter加入到HttpSecurity这个Filter数组中。接下来我们看看有多少对象调用了this.filters.add(filter) 方法。

在这里插入图片描述

​ 我们看到有各种的Configurer在调用HttpSecurity 对象的 addFilter(Filter filter) 方法,在往HttpSecurity 对象的fiters集合中添加Filter过滤器。

​ 以CorsConfigurer 为例子,CorsConfigurer 继承了 AbstractHttpConfigurer,重写了configure方法,并在该方法中调用了HttpSecurity http.addFilter(corsFilter)。当我们给HttpSecurity 配置了.cors()的时候,那么这个CorsFilter就会被正式的加入到HttpSecurity中,并对所有的请求进行拦截。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

四.Filter过滤器的排序

知道Filter过滤器的加载怎么加载到HttpSecurity之后,我们需要构建一个过滤器链DefaultSecurityFilterChain,

当后期所有的请求进来之后,都需要经过这个过滤器链的认证。

在这里插入图片描述

​ 在这一步是对所有的过滤器进行一个排序,并形成一个过滤器链。具体的排序规则详见FilterComparator,在FilterComparator中已经规定好了各个过滤器的顺序, 如下图:

在这里插入图片描述

五. 过滤器链的排序

​ 启动项目,在HttpSecurity的performBuid()方法打上断点,发现在此处对加入的所有的过滤器进行了一个排序操作。排序的规则和 FilterComparator一致。在我们这次的配置中,过滤器链中一共有13个过滤器,并且WebAsyncManagerIntegrationFilter在最前边。

在这里插入图片描述

六.过滤器对请求的处理

通过以上步骤,我们知道了当前项目中有13个过滤器,接下来依次对这13Filter进行打断点,向后台发送请求。

通过断点可以发现整个的请求顺序和DefaultSecurityFilterChain 中过滤器的顺序是一致的,WebAsyncManagerIntegrationFilter最先被处理,FilterSecurityInterceptor被最后处理。所有的Filter过滤器都通过了,才会进入到业务层。如果在某一个过滤器中验证失败,则该请求将会被拒绝。

到此一个完整的SpringSecurity请求拦截也就全部清楚了,在项目中到底有哪些过滤器,我们只需要打个断点看看过滤器链中有哪些,我们也可以自定义过滤器加入到HttpSecurity中即可。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值