Spring Security 自定义数据库认证(初尝试)

Spring Security 自定义数据库认证 学习笔记

适配个人实战案例:基于 Spring Boot 3 + Spring Security 6 + MyBatis 实现从MySQL数据库查询用户完成登录认证


一、学习目标

  1. 掌握 Spring Security 替换默认用户,使用数据库用户完成登录认证
  2. 理解 UserDetailsService 核心接口的作用
  3. 学会封装 UserDetails 用户信息对象
  4. 解决集成过程中的常见报错(空指针、类型转换、返回null等)

二、基础环境

1. 核心依赖

xml 复制代码
<!-- Spring Security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis + MySQL -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

2. 配置文件(application.yml)

配置数据库连接,无需额外配置Security

yaml 复制代码
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/你的数据库?useSSL=false
    username: root
    password: 你的密码
mybatis:
  mapper-locations: classpath:mapper/*.xml

三、核心代码实现

1. 数据库实体类(User)

com.sy.pojo.User 对应数据库user表

java 复制代码
@Data
public class User {
    private Integer id;
    private String username;
    private String password;
    private String realName;
    private String phone;
    private Integer status;
    private Date createTime;
}

2. Mapper 层(数据查询)

  1. UserMapper接口
java 复制代码
@Mapper
public interface UserMapper {
    // 根据用户名查询用户(认证核心方法)
    User findByUsername(String username);
}
  1. XML映射文件
xml 复制代码
<select id="findByUsername" resultType="com.sy.pojo.User">
    select * from user where username = #{username}
</select>

3. Service 层(认证核心)

  1. UserService接口(继承Security核心接口)
java 复制代码
public interface UserService extends UserDetailsService {
}
  1. UserServiceImpl实现类
java 复制代码
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    /**
     * Security 认证核心方法:根据用户名加载用户信息
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1. 从数据库查询用户
        User user = userMapper.findByUsername(username);
        
        // 2. 用户不存在,抛出异常
        if(user == null){
            throw new UsernameNotFoundException("用户不存在");
        }
        
        // 3. 封装为Security要求的UserDetails对象并返回
        return User.withUsername(user.getUsername())
                .password(user.getPassword())
                .authorities(AuthorityUtils.NO_AUTHORITIES)
                .build();
    }
}

4. Security 配置类

配置密码加密器(Security强制要求)

java 复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    // 密码加密:BCrypt算法
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

四、认证执行流程

  1. 用户提交登录表单 → Security 自动拦截
  2. 调用 loadUserByUsername 方法 → 根据用户名查数据库
  3. 返回 UserDetails 对象 → Security 自动比对密码
  4. 验证通过 → 登录成功;验证失败 → 报错

五、实战常见踩坑总结(重点)

报错信息 错误原因 解决方案
userMapper null 未加@Service / @Mapper 类上添加@Service、Mapper加@Mapper
类型转换异常 自定义User不能直接返回 封装为Security的User对象
UserDetails returned null 方法最后return null 必须return userDetails,禁止返回null
用户名不匹配 登录账号和数据库不一致 使用正确用户名登录

六、核心知识点

  1. UserDetailsService:Security认证的核心接口,自定义认证必须实现它
  2. UserDetails:Security规定的用户信息格式,必须封装后返回
  3. PasswordEncoder:密码加密接口,必须配置,否则无法认证
  4. 禁止返回nullloadUserByUsername 查到用户必须返回对象,没查到抛异常
相关推荐
桦说编程8 小时前
盘点并发集合里那些容易误判的行为
java·后端·性能优化
AI多Agent协作实战派8 小时前
AI多Agent协作系统实战(四十):AI说“没有错误“,系统判了“测试失败“——一个正则的误判
数据库·人工智能
IT爱学堂8 小时前
java版数据结构和算法+AI算法和技能学习指南
java·开发语言
隔窗听雨眠9 小时前
OceanBase接入DeepSeek:数据库与AI的深度融合如何改写企业数据规则
数据库·人工智能·oceanbase
lv__pf9 小时前
spring之整合mybatis【TL spring 12】
mysql·spring·mybatis
playboy1349 小时前
工作室 NAS 存储故障-办公室所有数据无法访问怎么办
数据库
evans在进步9 小时前
LeetCode 394:字符串解码——Java 单栈模拟与嵌套解析详解
java·python·leetcode
byxdaz10 小时前
jeston平台交叉编译Poppler库与预览pdf文件
数据库
SilicoCode10 小时前
江科大STM32入门:FLASH闪存详解——从结构原理到读写保护
数据库·mongodb
m0_5474866610 小时前
《Java程序设计与实践 》全套PPT课件2026
java·开发语言