• springsecurity入门篇


    一 介绍

    本节给知识追寻者给大家带来的是springSecurity入门篇,主要是简述下springSecrurity的启动原理和简单的入门搭建;

    公众号:知识追寻者

    知识追寻者(Inheriting the spirit of open source, Spreading technology knowledge;)

    二 核心模块介绍

    • spring-security-core ; 包含核心身份验证和access-contol类和接口,远程支持和基本配置AP;
    • spring-security-web: web , url登陆验证和访问控制;
    • spring-security-config: 支持xml 或者java注解配置;

    当然其模块远不止这些,比如CAS,ALC,Aspects,OpenI等等,对于入门我们了解核心即可;

    三 入门搭建

    3.1 依赖

    springboot 2.3.0

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

    3.2 控制层

    控制层定义一个接口,用于浏览器请求,请求成功后会返回 hello zszxz ;

      @GetMapping("hello")
        public String hello() {
    
            return "hello zszxz";
        }
    

    3.3 访问登陆页

    启动项目

    访问 localhost:8080/hello 会自动跳转至localhost:8080/login

    可以看到 接口就被保护起来了,访问接口需要进行账号密码登陆;那么账号密码在哪里?看tiao控制台打印的日志

    如下所示,一串uuid就是登陆密码;账号是 user;账号,密码输入后就会跳转至 localhost:8080/hello ;

    .UserDetailsServiceAutoConfiguration : 
    
    Using generated security password: 8f5b8238-9b35-482f-b2a5-bf440af5271b
    

    3.4 登陆原理解析

    由日志打印可以看出 是在 UserDetailsServiceAutoConfiguration 类中发现的密码;我们点击该类发现有个

    inMemoryUserDetailsManager 方法 里面有 properties.getUser(); 即获取用户,说明用户信息来自 SecurityProperties ;

        @Lazy
        public InMemoryUserDetailsManager inMemoryUserDetailsManager(SecurityProperties properties, ObjectProvider<PasswordEncoder> passwordEncoder) {
            User user = properties.getUser();
            List<String> roles = user.getRoles();
            return new InMemoryUserDetailsManager(new UserDetails[]{org.springframework.security.core.userdetails.User.withUsername(user.getName()).password(this.getOrDeducePassword(user, (PasswordEncoder)passwordEncoder.getIfAvailable())).roles(StringUtils.toStringArray(roles)).build()});
        }
    

    点击 SecurityProperties 类其有个内部静态类User, 如下所示,账号就是user, 密码就是UUID; roles是个ArrayList;配置文件的前缀 "spring.security"

    @ConfigurationProperties(
        prefix = "spring.security"
    )
    public class SecurityProperties {
    // 此处省略.........
    public static class User {
            private String name = "user";
            private String password = UUID.randomUUID().toString();
            private List<String> roles = new ArrayList();
            private boolean passwordGenerated = true;
    
    // 此处省略.........
    

    现在我们通过配置文件的方式改变账号密码,在application.yml配置账号密码如下

    spring:
      security:
        user:
          password: zszxz
          name: zszxz
    

    重启服务,访问http://localhost:8080/login 此时 的填入的表单账号密码就是 zszxz; 而且发现 控制台不再打印出uuid ;

    3.5 springSecurity基本原理

    仔细检测日志信息, 可以发现springSecurity模块的日志打印信息如下,其实现原理就是通过一串的Servlet过滤器进行基本实现,最后一个是FilterSecurityInterceptor 拦截器;

    [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@248deced, org.springframework.security.web.context.SecurityContextPersistenceFilter@677b8e13, org.springframework.security.web.header.HeaderWriterFilter@30331109, org.springframework.security.web.csrf.CsrfFilter@1bbae752, org.springframework.security.web.authentication.logout.LogoutFilter@64030b91, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@78faea5f,
    ...............
     .intercept.FilterSecurityInterceptor@2b4c3c29
    

    来自官网的图片如下;FilterChain 中包含了 Filter 和 Servlet , 其能够很快速的处理所有的URL请求; 当然每个具体的Filter 功能都不同,以后可能提到,有兴趣的读者也可以参照官网学习;

    比较重要的Filter

    • UsernamePasswordAuthenticationFilter
    • DigestAuthenticationFilter
    • BasicAuthenticationFilter
    • ExceptionTranslationFilter
    • FilterSecurityInterceptor

    四 加密方式

    官网有列出 基于 withDefaultPasswordEncoder 方式 创建 用户,这样并不是很推荐,原因是其账号密码会暴露在内存和编译的源码中,并不是很安全,如果要用于生产环境还需要对密码进行一次hash或者加密;

    UserBuilder users = User.withDefaultPasswordEncoder();
    User user = users
      .username("user")
      .password("password")
      .roles("USER")
      .build();
    User admin = users
      .username("admin")
      .password("password")
      .roles("USER","ADMIN")
      .build();
    

    官方提供了好多种其它方式进行加密:

    • DelegatingPasswordEncoder
    • BCryptPasswordEncoder
    • Argon2PasswordEncoder
    • Pbkdf2PasswordEncoder
    • SCryptPasswordEncoder

    它们的使用方式都差不多,示例如下,在使用时替换对应的加密对象即可

    SCryptPasswordEncoder encoder = new SCryptPasswordEncoder();
    String result = encoder.encode("myPassword");
    assertTrue(encoder.matches("myPassword", result));
    

    五 参考文档

    https://docs.spring.io/spring-security/site/docs/5.3.3.BUILD-SNAPSHOT/reference/html5/

  • 相关阅读:
    【Comet OJ Contest #15】孤独的吉姆 6
    【SSLOJ1467】U
    【SSLOJ1471】Y
    ajax调用webService
    泛型
    windows Server 2003 FTP
    ajax
    Linq 执行概念
    15款提高工作效率的工具分享
    Scrum是一种迭代式增量软件开发过程,通常用于敏捷软件开发
  • 原文地址:https://www.cnblogs.com/zszxz/p/13047642.html
Copyright © 2020-2023  润新知