• SpringSecurity篇-(1)-零配置启用


    最小配置启动

    • 首先你需要一个springboot项目
    • 作者当前使用的是springboot2.7.0版本

    如果用springboot2.7.1版本对应的springsecurity5.7.2版本,各位一定要注意下,5.7版本前后有一些配置是不一样的,我这里先记录5.7以后的配置

    Maven只需要引入两个依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    直接来一个helloworld吧!

    @RestController("/hello")
    public class HelloController {
        @RequestMapping
        public String hello(){
            return "Hello World!";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    尝试请求 http://localhost:9001/hello(端口自己配哈),SpringSecurity会默认跳到其登录页

    在这里插入图片描述

    在什么都不配置的情况下,SpringSecurity已经帮我们做了安全控制。仔细观察控制台日志可以看到为我们生成了一个默认密码,并且提示我们:此密码仅供开发模式使用,你一定要在生产环境更改安全配置

    在这里插入图片描述

    两个疑问

    作者看到这里的时候有两个疑问:

    1. 用户是什么?密码哪来的?
    2. 为啥我什么配置都没有,依赖多一个spring-boot-starter-security就要拦截我的helloworld?

    部分猿宝宝看到这里可能会生气,你怎么那么多问题?跟你学不知道啥时候能上手喔。别急,很多同学跟着别的博客配置是很快,运行的看起来也ok,但是让你加点啥,改点啥还是要百度,就说明你对这个框架不熟。当然不求甚解的确是当下解决问题的快捷方式,如果想要快速开始可以看下一篇了。

    源码解读

    在开始看源码前,建议大家自己去github上把springsecurity官方的源码下下来,build时候注意gradle和jdk版本就好了,这里就不做说明了。

    还有,为了方便学习,建议大家把trace日志打开,能够方便我i们在控制台查看SpringSecurity的调用链路

    logging.level.org.springframework.web=trace
    logging.level.org.springframework.security=trace
    
    • 1
    • 2

    从日志中看重点

    我们配置好日志后重新启动,观察下日志:

    在这里插入图片描述

    作者用飘逸的横线标出了四个本人认为关键性的信息

    1、期待初始化配置…

    我完整列出来

    eGlobalAuthenticationAutowiredConfigurer : Eagerly initializing 
    {org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration$WebSecurityEnablerConfiguration
    =org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration$WebSecurityEnablerConfiguration@e26af6}
    
    • 1
    • 2
    • 3

    说人话。eGlobalAuthenticationAutowiredConfigurer说,他非常渴望初始化,初始化什么?

    SpringBootWebSecurityConfiguration的内部类WebSecurityEnablerConfiguration初始化成他自己,这里先不过渡解读它为啥这么渴望,以及他初始化这个类到底要干嘛

    2、UserDetailsServiceAutoConfiguration说,我给你生成一个安全密码,那么看来自动生成用户密码是它干的事情

    到这个类,模糊搜一下日志内容,比如“Using generated”,能看到它相应的方法:

    private String getOrDeducePassword(SecurityProperties.User user, PasswordEncoder encoder) {
        String password = user.getPassword();
        if (user.isPasswordGenerated()) {
            logger.warn(String.format("%n%nUsing generated security password: %s%n%nThis generated password is for development use only. Your security configuration must be updated before running your application in production.%n", user.getPassword()));
        }
    
        return encoder == null && !PASSWORD_ALGORITHM_PATTERN.matcher(password).matches() ? "{noop}" + password : password;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    debug下它就知道密码是什么了

    在这里插入图片描述

    3、添加web访问表达式[authenticated]给任何请求

    edFilterInvocationSecurityMetadataSource : Adding web access control expression [authenticated] for any request
    
    • 1

    先不用管它是什么,总之它说给所有请求干的事情我们都要注意它要干嘛

    4、将要保护所有请求在…过滤链中

    那看看都有什么过滤器

    o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with 
    [org.springframework.security.web.session.DisableEncodeUrlFilter@506aabf6, 
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@5cbd94b2, 
    org.springframework.security.web.context.SecurityContextPersistenceFilter@7377781e, 
    org.springframework.security.web.header.HeaderWriterFilter@47e51549,
    org.springframework.security.web.csrf.CsrfFilter@3134153d, 
    org.springframework.security.web.authentication.logout.LogoutFilter@6d2a2560, 
    org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@4f2d995e, 
    org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@4bcaa195, 
    org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@6824b913, 
    org.springframework.security.web.authentication.www.BasicAuthenticationFilter@b46e103, 
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter@109f8c7e, 
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5edacf20, 
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter@756aadfc, 
    org.springframework.security.web.session.SessionManagementFilter@360e9c06, 
    org.springframework.security.web.access.ExceptionTranslationFilter@235d659c, 
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor@49a6f486]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    wow,这么多过滤,我的请求会不会变慢啊,这个先不说,是他们拦截的么?请求个helloworld试一下

    因为开了trace日志,你将看到如下壮观的镜像,我就不全列出来了

    在这里插入图片描述

    我只截到报错Access is denied这里,作者标记了一除 16/16,这个数字进度是什么意思?有心的同学可以数一下上面启动日志第四个重点就是SpringSecurity将我们所有的请求都用它列出的过滤器来保护,而过滤器的数量,就是16

    大胆猜测

    看到这里我们应该可以大胆的猜测:

    • SpringSecurity以AutoConfiguration机制配置了安全策略
    • 默认用户user是在其配置后的奖励品
    • SpringSecurity同时奖励了16个拦截器来保护我们的接口
    • 匿名访问helloworld被他们识别出并进行禁止

    这里先停止分析,过多的源码解读会变得枯燥,此系列不仅供大家做参考,作者也会经常复习,我怕我自己看不下去了

    接下来我们边学习配置,边解读原理

  • 相关阅读:
    智能生活从这里开始:数字孪生驱动的社区
    05【DAO开发的方式】
    MySQL数据库的事务
    【软考软件评测师】基于规则说明的测试技术下篇
    【无标题】激光焊接在医疗中的应用
    m基于PTS+TR的OFDM系统PAPR联合抑制算法matlab仿真
    WPS论文编写问题集(参考文献制作、公式居中及编号、公式影响行间距...)_长期更新中ing...
    16. 最接近的三数之和
    糖葫芦低通滤波器的设计
    javascript中科学计数法的数正常显示转换
  • 原文地址:https://blog.csdn.net/weixin_39080782/article/details/125436560