【Spring Security OAuth2】- spring security - 基本原理

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

基本原理

打开security的依赖

    compile('org.springframework.cloud:spring-cloud-starter-security')

打开之后默认就保护了所有的请求路径;访问任意一个都会跳转到一个默认的用户密码登录认证页面,

    用户名固定的:user
    密码,项目启动日志打印出来的(每次启动都不一样):Using generated security password: 60c4246b-735f-4f59-9a18-0861e1b7130a

默认的肯定不满足我们的需求,来看看怎么自定义配置

代码项目变更

从现在开始要改变项目模块来写安全代码了

启用该模块security-browser,安全相关的都在这里写,其他项目依赖安全模块即可;
该模块是基于浏览器的开发

注意:对于项目依赖,core的application.yml是不会生效的,只有在bobrowser中的application.yml才会生效

    dependencies {
        compile project(':security-core')
    }

编写第一个配置类

更改默认配置为form表单方式

    package cn.mrcode.imooc.springsecurity.securitybrowser;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    
    /**
     * @author : zhuqiang
     * @version : V1.0
     * @date : 2023/8/3 0:05
     */
    
    // WebSecurityConfigurerAdapter 适配器类。专门用来做web应用的安全配置
    @Configuration
    public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
    
        // 有三个configure的方法,这里使用http参数的
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // 最简单的修改默认配置的方法
            // 在v5+中,该配置(表单登录)应该是默认配置了
            // basic登录(也就是弹框登录的)应该是v5-的版本默认
            http
                    // 定义表单登录 - 身份认证的方式
                    .formLogin()
    //                .httpBasic()   // 切换为basic方式也很简单。感叹一下太强大
                    .and()
                    // 对请求授权配置:注意方法名的含义,能联想到一些
                    .authorizeRequests()
                    .anyRequest()
                    // 对任意请求都必须是已认证才能访问
                    .authenticated();
        }
    }

基本原理

202306181903365991.png

核心就是一组过滤器链。项目启动自动配置上的。

最核心的就是 Basic Authentication Filter 用来认证用户的身份;

一个过滤器处理一种认证方式;

对于username password认证过滤器来说,
* 会检查是否是一个登录请求,
* 是否包含username 和 password (也就是该过滤器需要的一些认证信息)
* 如果不满足则放行给下一个

下一个按照自身职责判定是否是自身需要的信息,

basic的特征就是在请求头中有 Authorization:Basic eHh4Onh4 的信息

中间可能还有更多的认证过滤器。 最后一环是 FilterSecurityInterceptor ,

这里会判定该请求是否能进行访问rest服务;判断的依据是:BrowserSecurityConfig中的配置;

如果被拒绝了就会抛出不同的异常(根据具体的原因)。

Exception Translation Filter 会捕获抛出的错误,然后根据不同的认证方式进行信息的返回提示

注意的是:绿色的过滤器可以配置是否生效,其他的都不能控制;

以上就是security最基本的一个原理,其他的衍生的功能都是基于这个架子进行扩展的

源码查看

源码查看思路:

上面描述了最基本的流程,这里把上面列出来的几个类关键部分打上断点,然后访问api进行跟进代码

  • org.springframework.security.web.access.intercept.FilterSecurityInterceptor#invoke

    大约120行InterceptorStatusToken token = super.beforeInvocation(fi);

  • org.springframework.security.web.access.ExceptionTranslationFilter#doFilter

    大约130行

  • org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#attemptAuthentication

    大约68行

  • org.springframework.security.web.authentication.www.BasicAuthenticationFilter#doFilterInternal

    大约150行

  • 任意一个api服务中

关键调试代码记录

    1. 访问一个服务
    2. 发现先走了 org.springframework.security.web.access.ExceptionTranslationFilter#doFilter
        为什么会先走这里,因为我们随意访问一个服务,都不满足前面几个认证过滤器的要求
    3. 执行后到了org.springframework.security.web.access.intercept.FilterSecurityInterceptor#invoke 中的 InterceptorStatusToken token = super.beforeInvocation(fi); 执行后就报错了
    4. 返回到了ExceptionTranslationFilter,并且被捕获到了异常信息 Access is denied (拒绝访问)
    5. 处理异常信息之后根据配置返回到了登录页面
    6. 登录之后,被拦截到 org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#attemptAuthentication
    7. 认证成功之后,又经过了 ExceptionTranslationFilter
    8. 接着又到了 FilterSecurityInterceptor 会验证是否有权限访问,如果有的话,InterceptorStatusToken token  会返回值,
    9. 下一步放行,由于之前处理的是一个登录请求,所以会有一个重定向,到我们访问的api中
      只要不是认证请求的话,前面的认证过滤器是不会走的,反而这两个类的流程都会走一遍 ExceptionTranslationFilter 、FilterSecurityInterceptor ; 看来这两个类是真的固定死的流程架子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值