SpringSecurity的使用

  1. 1. 一、引入依赖
  2. 2. 二、思路分析
    1. 2.0.1. 3.1 登录:
    2. 2.0.2. 3.2 校验:
  • 3. 三、实现
    1. 3.0.1. 用户密码加密存储
      1. 3.0.1.1. 3.1 运行这段测试代码
      2. 3.0.1.2. 3.2 为什么密码明文一样得到的,但每次调用encode方法的结果确实不一样的?
  • 3.1. 登录接口

  • 一、引入依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    <dependencies>

    <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>

    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
    </dependency>
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <scope>test</scope>
    </dependency>

    <!--mybatis-plus依赖-->
    <dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybatis-plus.version}</version>
    </dependency>

    </dependencies>

    新建一个springboot项目,启动只会打开会有一个springsecurity的登录页面,说明整合成功啦。

    二、思路分析

    3.1 登录:

    1. 自定义登录接口

      ​ 调用ProviderManager的方法进行认证, 如果认证通过生成 jwt

      ​ 把用户信息存入redis中

    2. 自定义 UserDetailsService

    ​ 在这实现类中去查询数据库

    3.2 校验:

    1. 定义 jwt 认证过滤器

      ​ 获取token’

      ​ 解析 token 获取其中的 userid

      ​ 从redis 中获取用户信息

      ​ 存入 securityContextHolder

    三、实现

    用户密码加密存储

    1
    2
    3
    4
    5
    6
    7
    8
    @Test
    public void TestBCryptPasswordEndoder() {
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    String encode1 = passwordEncoder.encode("1234");
    String encode2 = passwordEncoder.encode("1234");
    System.out.println(encode1);
    System.out.println(encode2);
    }

    3.1 运行这段测试代码

    结果如下,

    3.2 为什么密码明文一样得到的,但每次调用encode方法的结果确实不一样的?

    String encode(CharSequence rawPassword):加密原始密码。而BCrypt实现类会随机生成的salt盐来进行加密。

    ​ 这是因为它在内部运行的时候,会生成一个随机的salt, 前面有一段是相同的字符,它是salt盐跟原文进行一系列的处理再进行操作,所以虽然它的明文是相同的,但是得出来的结果是不同的。

    当然,解析这个也行

    1
    2
    3
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    System.out.println(passwordEncoder.matches("1234", "$2a$10$WcDdDjvgo8MJiiLjrD1qZ.2DbzsVhQ5bYukkHKKgvitOwCRcZPgae"));

    结果为: true

    登录接口

    ​ 接下来我们需要自定义登录接口,然后让springsecurity对这个接口放行(不用登录也能访问)。

    ​ 在接口中我们通过AuthenticationManager的 authenticate 方法来进行用户认证, 所以需要在SecurityConfig中配置把AuthenticationManager主入容器。

    ​ 认证成功的话要生成一个jwt,放入响应中返回,并且为了让用户下次请求的时候,能通过 jwt 识别出具体哪个用户, 我们需要把用户信息存入redis, 可以把用户id作为key。