技术栈
- Spring Boot
- Spring Security
- MyBatis Plus
- Redis
- MySQL
- Thymeleaf
- Swagger
- Mapstruct
- Lombok
- Java8
RBAC表设计
- tb_persmission: 权限表
- tb_role_permission: 角色权限表
- tb_role: 角色表
- tb_user_role: 用户角色表
- tb_user: 用户表
- persistent_login: 登录(记住我)功能使用,用于存储token信息
系统功能
- 登录、登出
- 用户增删改查、角色分配
- 角色增删改查、权限分配
登录
- 登录流程
- 后端登录配置
登出
- 登出流程
- 后端配置登出url ,自定义登出处理器
- 前端配置
自定义UserDetailsService
自定义异常
- 自定义访问拒绝异常
- 自定义认证异常
记住我配置
这段代码配置了Spring Security的Remember Me功能,即记住用户的登录状态。 具体来说,它配置了以下几点:
- 使用tokenRepository(persistentTokenRepository())方法指定了一个持久化的令牌存储器,用于保存和读取用户的令牌信息。
- 使用userDetailsService(domainUserDetailsService)方法指定了一个用户服务,用于根据令牌中的用户名加载用户的详细信息。
- 使用tokenValiditySeconds(3600)方法指定了令牌的有效期为3600秒,即一小时。
这里我们使用数据库存储用户令牌,令牌存储在persistent_login表中。persistentTokenRepository() 配置如下:
这样,当用户登录成功后,会在浏览器中保存一个包含用户名和加密签名的cookie,同时将令牌保存到数据库。
当用户再次访问时,会根据cookie中的信息自动登录。
AuthenticationFilter过滤器
创建一个过滤器AuthenticationFilter ,继承OncePerRequestFilter接口。在过滤器类中,重写doFilterInternal方法,用于获取请求中的token,验证token的合法性。
如果合法,就创建一个Authentication对象,并设置到SecurityContextHolder,同时刷新token过期时间。
在SecurityConfiguration配置类中,使用addFilterBefore方法,将自定义的过滤器添加到合适的位置,比如在UsernamePasswordAuthenticationFilter之前。
自定义权限校验
- 配置prePostEnabled = true,开启@PreAuthorize注解
- 自定义权限校验服务类
- 在控制器接口上配置权限注解
Docker部署
- 编写Dockerfile
- 打jar包
mvn clean package -DskipTests
- 构建镜像
docker build --rm -t spring-security-jdbc-sample:1.0 .
- 运行容器
docker run --name=sample \
--restart=always \
-p 8080:8080 \
-d spring-security-jdbc-sample:1.0
- 访问swagger文档 http://127.0.0.1:8080/doc.html#/home
我们也可以借助IDEA Docker插件进行docker部署,这里不再赘述。
接口测试
登录
- 输入用户名和密码,并记住我。这里使用超级管理员的账号进行登录
- 登录成功,返回token信息。注意这里因为配置了登录成功后的处理器,所以是直接返回请求的响应信息,并没有返回登录成功后的 index.html页面
请求权限接口
- 打开swagger文档 http://127.0.0.1:8080/doc.html#/home ,在头部配置上面返回的token信息
- 我们想要访问用户列表
- 未在头部配置token返回的错误信息
登出
执行登出操作,输入 curl -X POST http://127.0.0.1:8080/logout -H "X-TOKEN: tokenValue"
项目Gitlab地址
github.com/lenkax/spri… 欢迎提建议~