qidao123.com技术社区-IT企服评测·应用市场

标题: SpringBoot3整合SpringSecurity6(三)基于数据库的用户认证 [打印本页]

作者: 李优秀    时间: 2025-5-6 08:19
标题: SpringBoot3整合SpringSecurity6(三)基于数据库的用户认证
各人好,我是晓凡。
写在前面

上一篇文章中,我们了解了SpringSecurity怎么基于内存举行用户认证。但这还远远不够,在实际开辟中。
用户往往都存在于数据库,所以从这篇文章开始,我们就要开始学习基于数据库的用户认证。
一、认证流程

其实基于数据库的用户认证和基于内存认证大同小异,我们只需要将从内存获取用户信息,换成从数据库获取用户信息即可。
换成代码就是替换掉InMermoryUserDetailManager 实现类,本身去实现UserDetailsService,从数据库查询用户然后返回。

二、SpringBoot3整合数据库

在举行认证前,我们需要包管SpringBoot能正常整合数据库,查询用户信息。这里我们使用的数据库是MySQL8.0。
2.1 创建数据库、表、插入数据

①创建数据库
我们这里创建一个security-demo的数据库
  1. -- 创建数据库
  2. CREATE DATABASE `security-demo`;
  3. USE `security-demo`;
复制代码
② 创建用户
  1. -- 创建用户表
  2. CREATE TABLE `user`(
  3.         `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,  -- 主键ID
  4.         `username` VARCHAR(50) DEFAULT NULL ,  -- 用户名
  5.         `password` VARCHAR(500) DEFAULT NULL, -- 密码
  6.         `enabled` BOOLEAN NOT NULL -- 是否启用
  7. );
复制代码
③ 创建唯一索引
在这里一个用户的用户名username字段肯定是不能重复的,所以要为username创建唯一索引,包管username的唯一
  1. CREATE UNIQUE INDEX `user_username_uindex` ON `user`(`username`);
复制代码
④ 插入数据
为了方便测试,我们默认插入几个用户。为了安全起见,这里暗码采用SpringSecurity默认的bcrypt加密方式。不清楚的小伙可以先不消管,再后面的文章中会具体介绍到暗码加密算法
  1. -- 插入用户数据(密码是 "password" )
  2. INSERT INTO `user` (`username`, `password`, `enabled`) VALUES
  3. ('admin', '{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW', TRUE),
  4. ('xiezhr', '{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW', TRUE),
  5. ('xiaofan', '{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW', TRUE);
复制代码
2.2 设置Lombok

为了偷懒,我们还引入了Lombok 。 使用Lombok ,可以让我们避免写get、set、toString等样板式代码。堪称偷懒神器,解放了双手。
① 下面例举了怎么使用Lombok 来偷懒
② IDEA 中安装 Lombok 插件
我们需要再IDEA中安装了Lombok插件,才能正式愉快的使用Lombok。
根据你的系统依次点击菜单:
点击 Marketplace , 进入插件市场, 输入关键词 lombok, 搜刮该插件:

③ 引入依靠
在pom.xml文件中添加如下依靠
  1. <dependency>
  2.     <groupId>org.projectlombok</groupId>
  3.     <artifactId>lombok</artifactId>
  4.     <version>1.18.32</version>
  5. </dependency>
复制代码
2.3 引入Mybatis Plus

为了方便后续数据库增删改查等利用,我们引入MybatisPuls作为长期层框架。
① Mybatis Plus简介
有些小伙伴大概还不知道MybatisPuls,这里简单介绍一下,知道的小伙伴直接跳过即可。
用白话文说MybatisPuls是一款利用数据库的框架。它是一个 MyBatis 的加强工具,就像 iPhone手机一般都有个 plus 版本一样,它在 MyBatis 的基础上只做加强不做改变,为简化开辟、提高效率而生。
MyBatis Plus 的愿景是成为 MyBatis 最好的搭档,就像魂斗罗中的 1P、2P,基友搭配,效率翻倍。

② 引入依靠
为了整合mybatis-plus,我们需要在pom.xml中引入如下依靠
  1. <dependency>
  2.     <groupId>com.baomidou</groupId>
  3.     <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
  4.     <version>3.5.5</version>
  5. </dependency>
复制代码
2.4 引入MySQL依靠

我们这里数据库使用的是MySQL,所以还得引入MySQL相关依靠
  1. <dependency>
  2.     <groupId>mysql</groupId>
  3.     <artifactId>mysql-connector-java</artifactId>
  4.     <version>8.0.33</version>
  5. </dependency>
复制代码
2.5 完整依靠

最终完整依靠如下
  1. <dependencies>
  2.    
  3.     <dependency>
  4.         <groupId>org.springframework.boot</groupId>
  5.         <artifactId>spring-boot-starter-web</artifactId>
  6.     </dependency>
  7.    
  8.     <dependency>
  9.         <groupId>org.springframework.boot</groupId>
  10.         <artifactId>spring-boot-starter-security</artifactId>
  11.         <version>3.2.10</version>
  12.     </dependency>
  13.    
  14.     <dependency>
  15.         <groupId>org.projectlombok</groupId>
  16.         <artifactId>lombok</artifactId>
  17.         <version>1.18.32</version>
  18.     </dependency>
  19.    
  20.     <dependency>
  21.         <groupId>com.baomidou</groupId>
  22.         <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
  23.         <version>3.5.5</version>
  24.     </dependency>
  25.    
  26.     <dependency>
  27.         <groupId>org.springframework.boot</groupId>
  28.         <artifactId>spring-boot-starter-test</artifactId>
  29.         <scope>test</scope>
  30.     </dependency>
  31.    
  32.     <dependency>
  33.         <groupId>mysql</groupId>
  34.         <artifactId>mysql-connector-java</artifactId>
  35.         <version>8.0.33</version>
  36.     </dependency>
  37. </dependencies>
复制代码
2.6 设置数据源

application.yml文件中设置MySQL数据源,即mybatis-plus日记
  1. # MySQL数据源
  2. spring:
  3.   datasource:
  4.     driver-class-name: com.mysql.cj.jdbc.Driver
  5.     url: jdbc:mysql://localhost:3308/security-demo
  6.     username: root
  7.     password: 123456
  8. # MySQL日志
  9. mybatis-plus:
  10.   configuration:
  11.     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
复制代码
2.7 创建实体类
  1. package com.xiezhr.securityindbuser.entity;
  2. @TableName("user")
  3. @Data
  4. public class User {
  5.     @TableId(value = "id", type = IdType.AUTO)
  6.     private Integer id;
  7.     @TableField(value = "username")
  8.     private String username;
  9.     @TableField(value = "password")
  10.     private String password;
  11.    
  12.     @TableField(value = "enabled")
  13.     private Boolean enabled;
  14. }
复制代码
2.8 Mapper接口
  1. package com.xiezhr.securityindbuser.mapper;
  2. @Mapper
  3. public interface UserMapper extends BaseMapper<User> {
  4. }
复制代码
2.9 Service

① 接口
  1. package com.xiezhr.securityindbuser.service;
  2. public interface UserService extends IService<User> {
  3. }
复制代码
② 实现
  1. package com.xiezhr.securityindbuser.service.impl;
  2. @Service
  3. public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
  4. }
复制代码
2.10 Controller
  1. package com.xiezhr.securityindbuser.controller;
  2. @RestController
  3. @RequestMapping("/user")
  4. public class UserController {
  5.     @Autowired
  6.     private UserService userService;
  7.     @GetMapping("/list")
  8.     public List<User> getUserList(){
  9.         return userService.list();
  10.     }
  11. }
复制代码
2.11 测试是否正常获取数据

以上末节中,我们建立了各种类。结构如下

启动服务,欣赏器中输入:http://localhost:8080/user/list  看看是否能查出数据库中用户数据?

至此,我们已经乐成整合数据库,而且从数据库中查询出了用户信息。
接下来,我们要做的就是把认证流程从内存中获取用户信息替换成我们本身实现从数据库中查询用户信息。
三、基于数据库的用户认证

3.1 认证流程

通过之前基于内存认证分析,我们知道。只要实现UserDetailsService 接口的loadUserByUsername 方法就可以从数据库中获取用户信息。
3.2  创建DBUserDetailsManager

我们在service包下创建DBUserDetailsManager 来实现UserDetailsService 接口,替换从内存中获取用户信息。代码如下
  1. package com.xiezhr.securityindbuser.service.impl;
  2. public class DBUserDetailsManager implements UserDetailsService {
  3.     @Resource
  4.     private UserMapper userMapper;
  5.     @Override
  6.     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  7.         QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
  8.         //使用username构造查询条件
  9.         QueryWrapper<User> wrapper = queryWrapper.eq("username", username);
  10.                 //由于用户名不能重复,所以我们使用selectOne查询用户信息即可
  11.         User user = userMapper.selectOne(wrapper);
  12.         if (user == null) {
  13.             //用户不存在,抛出异常
  14.             throw new UsernameNotFoundException(username);
  15.         } else {
  16.             //由于现在还没有权限信息,所以我们构造一个空的权限信息
  17.             Collection< GrantedAuthority> authorities = new ArrayList<>();
  18.             return new org.springframework.security.core.userdetails.User(
  19.                     user.getUsername(),  //
  20.                     user.getPassword(),
  21.                     user.getEnabled(),
  22.                     true,  //用户账户是否没过期
  23.                     true, //用户凭证是否没过期
  24.                     true, //用户是否未被锁定
  25.                     authorities //用户权限信息
  26.             );
  27.         }
  28.     }
  29. }
复制代码
3.3 初始化UserDetailsService

说了一堆理论,那么我们怎么才能让springsecurity不从内存获取用户信息,而是通过上一步创建的DBUserDetailsManager 来查询用户信息。
接下来的就比较关键了,我们只需创建一个WebSecurityConfig,然后创建基于数据库的用户管理器dbUserDetailsManager即可
  1. package com.xiezhr.securityindbuser.config;
  2. @Configuration  //标明这个类为配置类,spring应用程序一启动,类中的been 就会被初始化在spring容器中
  3. @EnableWebSecurity  //开启spring security 自定义配置
  4. public class WebSecurityConfig {
  5.     @Bean
  6.     public UserDetailsService userDetailsService(){
  7.         //创建基于数据库的用户管理器
  8.         DBUserDetailsManager dbUserDetailsManager = new DBUserDetailsManager();
  9.         return dbUserDetailsManager;
  10.     }
  11. }
复制代码
当然我们也可以直接在DBUserDetailsManager类上添加@Component注解,也能实现同样的效果
3.4 测试一下

通过上面的步调,基于数据库的认证基本就完成了。
在整合数据库的时间我们插入了三个用户信息

下面我们来测试下结果,欣赏器中输入:http://localhost:8080/user/list

随便输入上面三个用户中一个,admin/password  xiezhr/password   xiaofan/password 即可正常访问接口

到此,我们乐成完成了基于数据库的用户认证功能,是不是很简单呢~

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4