【Spring Security 进阶实战】从内存用户到数据库,密码再也不用明文存了!
前言上一篇文章我们用五分钟搭建了第一个 Spring Security 项目实现了基本的登录认证功能。但那个项目有个致命的问题用户信息是存在内存里的而且密码还是明文的这就相当于保安手里只有一张临时名单重启项目名单就没了而且所有人的密码都写在明面上谁看了都知道。这在生产环境中是绝对不能接受的。今天我们就来解决这两个问题如何从数据库中查询用户信息如何对密码进行加密存储如何使用注解进行更细粒度的权限控制一、从数据库查询用户信息1.1 准备数据库和表首先我们需要创建一个用户表。为了简单起见我们只保留最基本的字段1.2 整合 MyBatis-Plus 操作数据库为了简化数据库操作我们使用 MyBatis-Plus。首先添加依赖然后在 application.yml 中配置数据库连接1.3 创建实体类和 Mapper创建用户实体类创建 Mapper 接口1.4 实现 UserDetailsService 接口Spring Security 提供了一个UserDetailsService接口我们只需要实现这个接口重写loadUserByUsername方法就能从数据库中查询用户信息了。就这么简单现在 Spring Security 就会自动从数据库中查询用户信息了。二、密码加密再也不用明文存密码了现在我们的密码还是明文存在数据库里的这太危险了万一数据库被拖库所有用户的密码都泄露了。Spring Security 提供了多种密码加密方式其中最推荐的是BCryptPasswordEncoder它是一种单向加密算法无法解密只能通过比对加密后的字符串来验证密码是否正确。2.1 配置密码加密器在 SecurityConfig 配置类中添加一个 Bean2.2 加密数据库中的密码现在我们需要把数据库中明文的密码改成加密后的。我们可以写个测试类来生成加密后的密码运行测试你会发现每次生成的加密密码都不一样但都能和原密码匹配。这就是 BCrypt 的强大之处它会自动生成随机盐即使两个用户的密码相同加密后的结果也不一样。把生成的加密密码更新到数据库中现在重启项目用用户名admin和密码123456登录就能成功登录了三、注解方式权限控制更细粒度的权限管理现在我们已经实现了从数据库查询用户和密码加密但所有登录的用户权限都是一样的。在实际项目中我们需要不同的用户有不同的权限比如管理员可以删除用户普通用户只能查看信息。Spring Security 提供了非常方便的注解方式权限控制只需要在方法上加上注解就能实现细粒度的权限管理。3.1 开启注解权限控制在启动类或者配置类上添加EnableMethodSecurity注解3.2 给用户分配不同的权限修改 UserDetailsServiceImpl给 admin 用户分配管理员权限3.3 在接口上添加权限注解创建一个用户管理接口现在测试一下用 admin 登录可以访问所有接口用 user 登录只能访问/system/user/list访问其他接口会返回 403 错误是不是非常方便只需要一个注解就能实现细粒度的权限控制四、退出登录功能最后我们来实现退出登录功能。Spring Security 已经帮我们实现好了只需要简单配置一下现在访问http://localhost:8080/logout就会退出登录跳转到登录页。五、总结今天我们解决了 Spring Security 入门项目中的两个核心问题实现了更实用的功能实现了从数据库查询用户信息不再使用内存用户使用 BCrypt 对密码进行加密存储提高了安全性使用注解方式实现了细粒度的权限控制实现了退出登录功能现在我们的权限系统已经基本可用了当然Spring Security 还有很多高级功能比如记住我、验证码、OAuth2.0 等等我们后面再慢慢讲。如果这篇文章对你有帮助别忘了点赞、收藏、关注三连有问题欢迎在评论区留言我会一一回复