Spring Boot 2.X 实战--Shiro (Token)登录和验证
主要介绍了 Spring Boot 整合 Spring Security 实现 Token 的登录和认证,这一小节中,我们将实现 Spring Boot 整合 Shiro 实现 Token 的登录和认证。
目录结构
1)Apache Shiro 简介
2)Shiro 项目配置
2.1)项目配置
3)开始使用 Shiro
2.1)实体类 Entity 和 Mapper
2.2)Token 配置
2.3)Shiro 配置
2.4)登录和注册接口
2.5)Shiro 的权限和角色
1)Apache Shiro 简介
在前面介绍过,Java 开发常用的安全框架有 Spring Security 和 Apache Shiro,这里将简要介绍一下 Shiro,Shiro 是一个功能强大的开源安全框架:
Apache Shiro™是一个功能强大且易于使用的 Java 安全框架,用于执行身份验证,授权,加密和会话管理。使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移动应用程序到最大的Web和企业应用程序。
对于使用 Shiro,需要了解其三个核心概念:
-
Subject:主题,是一个安全术语,表示“当前正在执行的用户”
-
SecurityManager : 安全管理器,是 Shiro 的核心,提供各种安全管理的服务和管理所有的 Subject。
-
Realm : Realm 是应用程序和安全数据之间的“桥梁”或者“连接器”,当 Shiro 需要和安全数据(例如:用户账户信息)交互以实现身份验证(登录认证)和授权(访问控制),Shiro 会通过其配置的一个或者多个 Realm 实现。
扩展阅读:http://shiro.apache.org/architecture.html
2)Shiro 项目配置
新建一个项目,07-shiro,记得勾选 MySQL,MyBatis,Web 依赖。对于 Maven 项目,同样是在文章最后面给出对应的依赖配置。
Gradle 项目配置
1 implementation 'org.springframework.boot:spring-boot-starter-web'
2 implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.2'
3 runtimeOnly 'mysql:mysql-connector-java'
4 testImplementation 'org.springframework.boot:spring-boot-starter-test'
5 // https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring-boot-web-starter
6 compile group: 'org.apache.shiro', name: 'shiro-spring-boot-web-starter', version: '1.5.2'
7 // https://github.com/jwtk/jjwt
8 compile 'io.jsonwebtoken:jjwt-api:0.11.1'
9 runtime 'io.jsonwebtoken:jjwt-impl:0.11.1',
10 // Uncomment the next line if you want to use RSASSA-PSS (PS256, PS384, PS512) algorithms:
11 //'org.bouncycastle:bcprov-jdk15on:1.60',
12 // or 'io.jsonwebtoken:jjwt-gson:0.11.1' for gson
13 'io.jsonwebtoken:jjwt-jackson:0.11.1'
2.1)项目配置
配置 MySQL 数据库和 MyBatis 驼峰命名转换,application.properties
1# 数据库 URL、用户名、密码、JDBC Driver更换数据库只需更改这些信息即可
2# MySQL 8 需要指定 serverTimezone 才能连接成功
3spring.datasource.url=jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
4spring.datasource.password=xiaoxian
5spring.datasource.username=root
6spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
7# MyBatis 驼峰命名转换
8mybatis.configuration.map-underscore-to-camel-case=true
添加 @MapperScan
1@MapperScan("org.xian.security.mapper")
2public class SecurityApplication {}
3)开始使用 Shiro
项目的主要结构:
-
controller 包:API 接口
-
service 包:为 API 提供接口服务
-
mapper 包:MyBatis Mapper 类
-
entity 包:实体类
-
Shiro 包:Token 拦截验证、Token 生成、Shiro 的 Realm 等配置
MyResponse :公共 Response 返回消息类:
1public class MyResponse implements Serializable {
2 private static final long serialVersionUID = -2L;
3 private String status;
4 private String message;
5}
2.1)实体类 Entity 和 Mapper
这里的表结构和上一节一样, 用户表 sys_user
字段 | 类型 | 备注 |
---|---|---|
user_id | bigint | 自增主键 |
username | varchar(18) | 用户名,非空唯一 |
password | varchar(128) | 密码,非空 |
user_role | varchar(8) | 用户角色(USER / ADMIN) |
user_permission | varchar(36) | 用户权限 |
这里用户角色有 USER / ADMIN ,对于一个用户可能有多个角色的情况暂不考虑。
Shiro 可以指定相应的权限控制,比如 Update 的权限,Create 的权限,使得可以更加细粒度的控制。这里的权限用英文分号 , 直接隔开,例如:update,create,delete ,表示该用户具有 Update 等三个权限。
密码使用 HASH 散列加密。
SQL
1create table sys_user
2(
3 user_id bigint auto_increment,
4 username varchar(18) not null unique,
5 password varchar(128) not null,
6 user_role varchar(8) not null,
7 user_permission varchar(36) not null,
8 constraint sys_user_pk
9 primary key (user_id)
10);
Entity 实体类:新建 package,名称为 entity 。在 entity下新建一个 SysUser 类:
1public class SysUser implements Serializable {
2 private static final long serialVersionUID = 4522943071576672084L;
3 private Long userId;
4 private String username;
5 private String password;
6 private String userRole;
7 private String userPermission;
8 // 省略 getter setter constructor
9}
Mapper 接口类:新建包 mapper,新建 SysUserMapper 类:
1public interface SysUserMapper {
2 /** 往 sys_user 插入一条记录
3 * @param sysUser 用户信息