SpringSecurity整合MyBatis实现数据库认证的详细步骤

 更新时间:2026年04月17日 09:40:24   作者:Flittly  
本文介绍了如何将MySQL数据库中的用户信息接入SpringSecurity,并介绍了MyBatis的整合以及基于数据库的自定义认证,主要内容包括问题引入、解决方案、原理阐释、代码实现和数据库准备等步骤,需要的朋友可以参考下

本章将介绍如何将 MySQL 数据库中的用户信息接入 Spring Security,告别配置文件中的内存用户。

一、问题切入

第一章中我们通过配置文件指定用户:

spring:
  security:
    user:
      name: flittly
      password: 123456

这种方式存在明显缺陷:

  • 用户信息写在代码中,无法动态管理
  • 密码以明文形式存储,安全性低
  • 生产环境不应使用配置文件明文密码
  • 无法扩展更多用户,无法支持注册/注销等功能

我们需要一个可扩展的方案,将数据库中的用户信息加载到 Spring Security 中。

二、解决方案:引入 MyBatis

pom.xml 中添加 MyBatis Starter 和 MySQL 驱动:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

三、配置数据源连接

application.yml 中配置数据库连接:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/spring_security_demo
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: cn.edu.nnu.opengms.ss02.entity

四、原理阐释:认证流程

4.1 核心接口

Spring Security 的认证体系围绕以下核心接口展开:

接口作用
UserDetailsService根据用户名加载用户信息
UserDetails用户信息封装对象
PasswordEncoder密码验证器
Authentication认证令牌

4.2 认证流程详解

整个认证流程涉及多个组件的协作:

用户提交登录表单(用户名 + 密码)
    ↓
UsernamePasswordAuthenticationFilter 拦截请求
    ↓ 提取用户名
DaoAuthenticationProvider.getUserDetails(username)
    ↓ 调用
UserDetailsService.loadUserByUsername(username)
    ↓ 调用 MyBatis Mapper
从数据库查询用户信息
    ↓ 返回
构建 UserDetails 对象(含密码、权限信息)
    ↓
PasswordEncoder.matches() 验证密码
    ↓ 匹配成功
Authentication 认证成功,创建认证令牌
    ↓
SecurityContextHolder.getContext().setAuthentication()
    ↓
重定向到成功页面

UserDetailsService 是 Spring Security 认证体系的核心接口,负责根据用户名加载用户信息。

4.3 密码编码器

Spring Security 7.x 要求必须配置密码编码器,支持多种编码方式:

  • BCrypt:推荐,单向哈希算法,内置随机盐
  • Argon2:现代密码哈希算法
  • PBKDF2:基于密钥推导
  • Scrypt:计算密集型算法

BCrypt 是目前最常用的选择,它具有以下特点:

  • 单向哈希:无法从哈希值反向推导原始密码
  • 内置盐:每次加密生成不同的哈希值,即使相同密码也不一样
  • 强度可调:通过 work factor 调整计算时间

五、代码实现

5.1 Users 实体类

对应数据库中的 users 表:

@Data
public class Users implements Serializable {
    private Long id;
    private String username;
    private String password;
    private String email;
    private String phone;
    private Boolean enabled;
    private Date createTime;
    private Date updateTime;
}

5.2 Mapper 接口

定义根据用户名查询用户的方法:

@Mapper
public interface UsersMapper {
    Users selectByLoginAct(@Param("loginAct") String loginAct);
}

5.3 Mapper XML

<mapper namespace="cn.edu.nnu.opengms.ss02.mapper.UsersMapper">
    <select id="selectByLoginAct" resultMap="BaseResultMap">
        SELECT * FROM users WHERE username = #{loginAct}
    </select>
</mapper>

5.4 UserService 接口

定义服务接口,继承 UserDetailsService

public interface UserService extends UserDetailsService {
    // 只需实现 loadUserByUsername 方法
}

5.5 UserServiceImpl 实现

核心实现类,从数据库加载用户:

@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UsersMapper usersMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Users users = usersMapper.selectByLoginAct(username);
        if (users == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        // 将数据库用户转换为 Spring Security 的 UserDetails 对象
        UserDetails userDetails = User.builder()
                .username(users.getUsername())
                .password(users.getPassword())
                .authorities(AuthorityUtils.NO_AUTHORITIES)
                .build();
        return userDetails;
    }
}

这里的 User 是 Spring Security 提供的构建器类,用于简化 UserDetails 对象的创建。

5.6 PasswordEncoder 配置

在 Spring 容器中注册密码编码器:

@Configuration
public class SecurityConfig {
    @Bean
    public PasswordEncoder passwordEncoder() {
        // BCrypt:单向哈希算法,自带随机盐,安全性高
        return new BCryptPasswordEncoder();
    }
}

六、数据库准备

创建数据库和用户表:

CREATE TABLE `users` (
    `id` BIGINT PRIMARY KEY AUTO_INCREMENT,
    `username` VARCHAR(50) NOT NULL UNIQUE,
    `password` VARCHAR(100) NOT NULL,
    `email` VARCHAR(100),
    `phone` VARCHAR(20),
    `enabled` TINYINT(1) DEFAULT 1,
    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
    `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

注意:数据库中的密码必须是 BCrypt 加密后的密文,可以使用 BCrypt 工具类生成。

6.1 使用 IDEA 插件 Free MyBatis Tool 生成 Mapper 与 XML

在这个模块里,你也可以使用 IntelliJ IDEA 插件 Free MyBatis Tool 来快速生成基础代码,减少手写重复劳动。

常见流程如下:

  1. 在 IDEA 安装插件:Free MyBatis Tool
  2. 配置数据源并连接目标数据库(如 spring_security_demo
  3. 选中目标表(如 users)后执行代码生成
  4. 生成实体类、Mapper 接口、Mapper XML(以及可选 Service/Controller 模板)

生成后建议重点检查以下几项(这一步很重要):

  • namespace 是否与 Mapper 接口全限定名一致
  • XML 中 id 是否与接口方法名一致(如 selectByLoginAct
  • mapper-locations 是否与 XML 实际路径一致
  • 参数名与 SQL 占位符是否一致(必要时配合 @Param

示例(生成后可按项目需要补充自定义查询):

@Mapper
public interface UsersMapper {
    Users selectByLoginAct(@Param("loginAct") String loginAct);
}
<mapper namespace="cn.edu.nnu.opengms.ss02.mapper.UsersMapper">
    <select id="selectByLoginAct" resultMap="BaseResultMap">
        SELECT * FROM users WHERE username = #{loginAct}
    </select>
</mapper>

提示:代码生成能提高效率,但不要完全依赖默认模板。安全相关字段(如 passwordenabled)和登录查询 SQL 仍建议人工复核。

七、核心概念总结

概念说明
UserDetailsService自定义认证服务接口,loadUserByUsername() 方法由框架自动调用
UserDetails用户信息封装对象,包含用户名、密码、权限
UserDetailsBuilder构建器,简化 UserDetails 对象创建
PasswordEncoder密码编码器,Spring Security 7.x 必须配置
认证流程框架自动调用数据库查询,验证密码

八、总结

本篇文章介绍了以下核心概念:

  1. UserDetailsService:自定义认证服务接口
  2. UserDetails:用户信息封装对象
  3. PasswordEncoder:密码编码器,必须配置
  4. 认证流程:框架自动调用数据库查询,验证密码
  5. BCrypt:推荐使用的密码编码算法

以上就是SpringSecurity整合MyBatis实现数据库认证的详细步骤的详细内容,更多关于SpringSecurity MyBatis数据库认证的资料请关注脚本之家其它相关文章!

相关文章

  • 最新Java JDK安装配置的图文教程

    最新Java JDK安装配置的图文教程

    随着技术的不断发展和更新,Java作为世界上最为流行的编程语言之一,其开发工具包(JDK)也在持续更新中,本文旨在为您提供最新版JDK的详细安装步骤,通过图文结合的方式,帮助您轻松完成Java开发环境的搭建,需要的朋友可以参考下
    2025-07-07
  • Java实现url加密处理的方法示例

    Java实现url加密处理的方法示例

    这篇文章主要介绍了Java实现url加密处理的方法,涉及java基于base64、编码转换实现加密解密相关操作技巧,需要的朋友可以参考下
    2017-06-06
  • 一问详解SpringBoot配置文件优先级

    一问详解SpringBoot配置文件优先级

    在SpringBoot项目当中,我们要想配置一个属性,可以通过这三种方式当中的任意一种来配置都可以,那么优先级怎么算,本文主要介绍了一问详解SpringBoot配置文件优先级,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Java利用Stream API提高代码的简洁度和效率的操作方法

    Java利用Stream API提高代码的简洁度和效率的操作方法

    Stream API是Java 8引入的一项新特性,它提供了一种声明性、函数式的编程方式来处理集合(例如List、Set)等数据,那么Stream API到底能带来什么好处呢?今天,我就结合我多年的开发经验,带你深入了解如何使用Stream API优化代码,提高效率,减少冗余
    2025-08-08
  • Java使用Spire.Presentation for Java将PPT转换为PDF

    Java使用Spire.Presentation for Java将PPT转换为PDF

    文章介绍Java开发者使用Spire.PresentationforJava将PPT转换为PDF,支持跨平台兼容、PDF/A标准、加密、隐藏幻灯片和自定义页面大小等高级功能,满足文档分发、归档与安全需求
    2025-10-10
  • SpringBoot使用Swagger范例讲解

    SpringBoot使用Swagger范例讲解

    Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化 Restful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法、参数和模型紧密集成到服务器端的代码,允许API来始终保持同步
    2022-07-07
  • 合并有序数组的实现(java与C语言)

    合并有序数组的实现(java与C语言)

    这篇文章主要介绍了合并有序数组的实现(java与C语言)的相关资料,这里对有序数组的合并分享了java版本和C语言版本的示例,需要的朋友可以参考下
    2017-08-08
  • 一文详解Java中流程控制语句

    一文详解Java中流程控制语句

    在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。也就是说,程序的流程对运行结果有直接的影响。所以,我们必须清楚每条语句的执行流程。本文就来通过一些示例带大家详细了解一下
    2022-10-10
  • Linux Ubuntu系统下配置JDK环境、MySQL环境全过程

    Linux Ubuntu系统下配置JDK环境、MySQL环境全过程

    众所周知Ubuntu是一种基于Linux的操作系统,它提供了一个稳定、安全和易于使用的环境,下面这篇文章主要给大家介绍了关于Linux Ubuntu系统下配置JDK环境、MySQL环境的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-07-07
  • Java实现扫雷游戏详细代码讲解

    Java实现扫雷游戏详细代码讲解

    windows自带的游戏《扫雷》是陪伴了无数人的经典游戏,本文将利用Java语言实现这一经典的游戏,文中的示例代码讲解详细,感兴趣的可以学习一下
    2022-05-05

最新评论