• Spring Security解决认证与授权的框架


    Spring Security是用于解决认证与授权的框架。

    在根项目下创建新的xxx子模块,最基础的依赖项包括spring-boot-starter-webspring-boot-starter-security(为避免默认存在的测试类出错,应该保留测试的依赖项spring-boot-starter-test),完整的xxxpom.xml为:

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0</modelVersion>
    5. <!-- 父级项目 -->
    6. <parent>
    7. <groupId>xxx</groupId>
    8. <artifactId>xxx</artifactId>
    9. <version>xxx</version>
    10. </parent>
    11. <!-- 当前项目的信息 -->
    12. <groupId>xxx</groupId>
    13. <artifactId>xxx</artifactId>
    14. <version>xxx</version>
    15. <!-- 当前项目需要使用的依赖项 -->
    16. <dependencies>
    17. <!-- Spring Boot Web:支持Spring MVC -->
    18. <dependency>
    19. <groupId>org.springframework.boot</groupId>
    20. <artifactId>spring-boot-starter-web</artifactId>
    21. </dependency>
    22. <!-- Spring Boot Security:处理认证与授权 -->
    23. <dependency>
    24. <groupId>org.springframework.boot</groupId>
    25. <artifactId>spring-boot-starter-security</artifactId>
    26. </dependency>
    27. <!-- Spring Boot Test:测试 -->
    28. <dependency>
    29. <groupId>org.springframework.boot</groupId>
    30. <artifactId>spring-boot-starter-test</artifactId>
    31. <scope>test</scope>
    32. </dependency>
    33. </dependencies>
    34. </project>

    调整完成后,即可启动项目,在启动的日志中,可以看到类似以下内容:

    Using generated security password: 2abb9119-b5bb-4de9-8584-9f893e4a5a92
    

    Spring Security有默认登录的账号和密码(以上提示的值),密码是随机的,每次启动项目都会不同。

    Spring Security默认要求所有的请求都是必须先登录才允许的访问,可以使用默认的用户名user和自动生成的随机密码来登录。在测试登录时,在浏览器访问当前主机的任意网址都可以(包括不存在的资源),会自动跳转到登录页(是由Spring Security提供的,默认的URL是:http://localhost:8080/login),当登录成功后,会自动跳转到此前访问的URL(跳转登录页之前的URL),另外,还可以通过 http://localhost:8080/logout 退出登录。

    Spring Security的依赖项中包括了Bcrypt算法的工具类,Bcrypt是一款非常优秀的密码加密工具,适用于对需要存储下来的密码进行加密处理。

    1. import org.junit.jupiter.api.Test;
    2. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    3. public class BcryptPasswordEncoderTests {
    4. private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    5. @Test
    6. public void testEncode() {
    7. // 原文相同的情况,每次加密得到的密文都不同
    8. for (int i = 0; i < 10; i++) {
    9. String rawPassword = "123456";
    10. String encodedPassword = passwordEncoder.encode(rawPassword);
    11. System.out.println("rawPassword = " + rawPassword);
    12. System.out.println("encodedPassword = " + encodedPassword);
    13. }
    14. // rawPassword = 123456
    15. // encodedPassword = $2a$10$HWuJ9WgPazrwg9.isaae4u7XdP7ohH7LetDwdlTWuPC4ZAvG.Uc7W
    16. // encodedPassword = $2a$10$rOwgZMpDvZ3Kn7CxHWiEbeC6bQMGtfX.VYc9DCzx9BxkWymX6FbrS
    17. // encodedPassword = $2a$10$H8ehVGsZx89lSVHwBVI37OkxWm8LXei4T1o5of82Hwc1rD0Yauhky
    18. // encodedPassword = $2a$10$meBbCiHZBcYn7zMrZ4fPd.hizrsiZhAu8tmDk.P8QJcCzSQGhXSvq
    19. // encodedPassword = $2a$10$bIRyvV29aoeJLo6hh1M.yOvKoOud5kC7AXDMSUW4tF/DlcG0bLj9C
    20. // encodedPassword = $2a$10$eq5BuoAiQ6Uo0.TOPZOFPuRNlPl3t2GoTlaFoYfBu3/Bo3tLzx.v2
    21. // encodedPassword = $2a$10$DhTSwQfNdqrGgHRmILmNLeV0jt3ZXL435xz0fwyZ315ciI5AuI5gi
    22. // encodedPassword = $2a$10$T.8/ISoLOdreEEkp4py36O0ZYfihDbdHDuIElZVF3uEgMOX.8sPcK
    23. // encodedPassword = $2a$10$hI4wweFOGJ7FMduSmcjNBexbKFOjYMWl8hkug0n0k1LNR5vEyhhMW
    24. // encodedPassword = $2a$10$b4ztMI6tWoiJuoDYKwr7DOywsPkkCdvDxbPfmEsLdp11NdABS7wyy
    25. }
    26. @Test
    27. public void testMatches() {
    28. String rawPassword = "123456";
    29. String encodedPassword = "$2a$10$hI4wweFOGJ7FMduSmCjNBexbKFOjYMWl8hkug0n0k1LNR5vEyhhMW";
    30. boolean matchResult = passwordEncoder.matches(rawPassword, encodedPassword);
    31. System.out.println("match result : " + matchResult);
    32. }
    33. }

    Spring Security的认证机制中包含:当客户端提交登录后,会自动调用UserDetailsService接口(Spring Security定义的)的实现类对象中的UserDetails loadUserByUsername(String username)方法(根据用户名加载用户数据),将得到UserDetails类型的对象,此对象中应该至少包括此用户名对应的密码、权限等信息,接下来,Spring Security会自动完成密码的对比,并确定此次客户端提交的信息是否允许登录!类似于:

    1. // Spring Security的行为
    2. UserDetails userDetails = userDetailsService.loadUserByUsername("xxx");
    3. // Spring Security将从userDetails中获取密码,用于验证客户端提交的密码,判断是否匹配

    所以,要实现Spring Security通过数据库的数据来验证用户名与密码(而不是采用默认的user用户名和随机的密码),则在此模块的根包下创建security.UserDetailsServiceImpl类,实现UserDetailsService接口,并重写接口中的抽象方法:

     

  • 相关阅读:
    软路由R4S+iStoreOS实现公网远程桌面局域网内电脑
    【Linux】《Linux命令行与shell脚本编程大全 (第4版) 》笔记-Chapter8-管理文件系统
    【M365运维】给从本地同步到O365的DL添加 Send As权限
    Java项目:SSM物业缴费管理系统
    解决javascript报错:SyntaxError: Invalid Unicode escape sequence
    c语言基础:L1-001 Hello World
    【python】time
    掌握SpringMVC开发环境搭建
    数据库:管理数据库课堂练习
    实验二.面向对象基础
  • 原文地址:https://blog.csdn.net/ClearDream__/article/details/125459999