spring boot(学习笔记第十四课)

spring boot(学习笔记第十四课)

  • Spring Security的密码加密,基于数据库认证

学习内容:

  1. Spring Security的密码加密
  2. 基于数据库认证

1. Spring Security的密码加密

  1. 如果用户的密码保存在数据库中是以明文保存,对于公司的安全将是灾难性的,哪个公司也不会允许用户数据使用明文保存。这里练习使用加密之后的密码进行认证。
    注意,这样公司的数据库里面是没有用户的明文密码,即使数据库泄露,也不会暴漏用户的明文密码在这里插入图片描述
  2. 实现密码加密
    • 配置passwordEncoder
      @Bean
      PasswordEncoder passwordEncoder() {
         return new BCryptPasswordEncoder(10);
      }
      
    • 手动根据明文密码生成密文密码
      bcrypt转换工具
      注意,每次生成的密码都不一样,但是每个生成的都好用
      在这里插入图片描述
    • 使用生成的密文进行用户的创建。
       @Bean
          UserDetailsService userDetailsService() {
              InMemoryUserDetailsManager users =
                      new InMemoryUserDetailsManager();
              users.createUser(User.withUsername("finlay_user")
                      .password("$2a$10$uwwZ5EyWbFnnw3JG53rqQ.VJUm/.Pl9Ko1CUP5Aqc2kuBr2Bx7bc.")
                      .roles("USER")
                      .build());
      
    • 再次进行认证。
      在这里插入图片描述

2. 基于数据库认证

以上练习了基于内存的认证,实际上,正式的系统开发都是使用数据库进行认证,在这里练习使用使用数据库的用户数据进行认证。这里使用postgresql

  1. 首先创建数据库需要的表
    • 创建USER
      CREATE TABLE "USER"(
      id int,
      username varchar(32),
      password varchar(255),
      enabled int,
      locked int,
      PRIMARY KEY(id)
      );
      
    • 创建ROLE
      CREATE TABLE "ROLE"(
      id int,
      name varchar(32),
      nameZh varchar(255),
      PRIMARY KEY(id)
      );
      
    • 创建USER_ROLE表(userrole的关系表)
      CREATE TABLE "USER_ROLE"(
      id int,
      uid int,
      rid int,
      PRIMARY KEY(id)
      );
      
    • 用户数据如下:
      • USER
        在这里插入图片描述
      • ROLE
        在这里插入图片描述
      • USER_ROLE
        在这里插入图片描述
      • USERROLE的关系
        			with uur as ( 
        			    select
        			        * 
        			    from
        			        "USER" u 
        			        inner join "USER_ROLE" ur 
        			            on u.id = ur.uid
        			)
        			select username,namezh,name as rolename from uur 
        			    inner join "ROLE" r 
        			        on uur.rid = r.id
        
        在这里插入图片描述
  2. 引入必要的依赖
    		<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>3.0.3</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.2.9</version>
            </dependency>
    
    这里repository使用mybatis,所以引入mybatis的依赖包。
  3. application.properties定义数据库连接信息。
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/springboot
    spring.datasource.username=finlay
    spring.datasource.password=123456
    
  4. 定义mybatisinterface,以及xml文件
    • 定义UserRole的实体类
      @Data
      public class Role {
          private Integer id;
          private String name;
          private String nameZh;
      }
      
      @Data
      public class User implements UserDetails {
          private Integer id;
          private String username;
          private String password;
          private Boolean enabled;
          private Boolean locked;
          private List<Role> roles;
      
          @Override
          public Collection<? extends GrantedAuthority> getAuthorities() {
              List<SimpleGrantedAuthority> authorities = new ArrayList<>();
              for (Role role : roles) {
                  authorities.add(new SimpleGrantedAuthority(role.getName()));
              }
              return authorities;
          }
      
          @Override
          public String getPassword() {
              return this.password;
          }
      
          @Override
          public String getUsername() {
              return this.username;
          }
      
          @Override
          public boolean isAccountNonExpired() {
              return true;
          }
      
          @Override
          public boolean isAccountNonLocked() {
              return !this.locked;
          }
          @Override
          public boolean isCredentialsNonExpired(){
              return true;
          }
          @Override
          public boolean isEnabled(){
              return this.enabled;
          }
      }
      
    • 配置mybatis
      @Mapper
      public interface UserMapper {
          User loadUserByUserName(String usernam);
          List<Role> getUserRolesByUid(Integer id);
      }
      
    • 配置mybatisxml配置文件
      <!DOCTYPE mapper
              PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <mapper namespace="com.example.demo.repository.mybatis.UserMapper">
          <select id="loadUserByUserName" resultType="com.example.demo.authentication.User">
              select * from "USER" where username=#{username}
          </select>
          <select id="getUserRolesByUid" resultType="com.example.demo.authentication.Role">
              select * from "ROLE" r, "USER_ROLE" ur where r.id=ur.rid and ur.uid=#{id}
          </select>
      </mapper>
      
  5. 定义UserDetailsService
    @Service
    public class UserService implements UserDetailsService {
        @Autowired
        public UserMapper userMapper;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = userMapper.loadUserByUserName(username);
            if (user == null) {
                throw new UsernameNotFoundException("username is not found");
            }
            user.setRoles(userMapper.getUserRolesByUid(user.getId()));
            return user;
        }
    }
    
    注意,这里生成了UserDetailsServicebean,所以spring boot security的的认证处理,都会使用这个bean
  6. 整体的架构
    在这里插入图片描述
  7. 测试认证结果
    在这里插入图片描述

相关推荐

  1. word

    2024-07-21 09:04:01       24 阅读
  2. Python学习笔记天(OpenCV安装)

    2024-07-21 09:04:01       56 阅读
  3. 大模型学习

    2024-07-21 09:04:01       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-21 09:04:01       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-21 09:04:01       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-21 09:04:01       45 阅读
  4. Python语言-面向对象

    2024-07-21 09:04:01       55 阅读

热门阅读

  1. 内存管理(知识点)

    2024-07-21 09:04:01       18 阅读
  2. 1604 - 高精度除单精度

    2024-07-21 09:04:01       14 阅读
  3. 数据结构(功能受限的表-栈&队列)

    2024-07-21 09:04:01       18 阅读
  4. Linux 下部署 syncthing 中继服务器

    2024-07-21 09:04:01       21 阅读
  5. 云计算遭遇的主要安全威胁

    2024-07-21 09:04:01       14 阅读
  6. 服务发现的艺术:Eureka中实现分布式服务目录

    2024-07-21 09:04:01       18 阅读
  7. 终端创建py虚拟环境

    2024-07-21 09:04:01       15 阅读
  8. log4j2启动异步日志与动态修改日志级别

    2024-07-21 09:04:01       17 阅读
  9. Leetcode【拥有最多糖果的孩子】

    2024-07-21 09:04:01       19 阅读
  10. python-docx,一个超酷的word处理Python库!

    2024-07-21 09:04:01       15 阅读