# 开始使用
开始使用前,请先了解框架其他说明文档,以便快速进入开发状态。
# Step.1 - 加入Maven依赖
导入依赖库包
可在maven中央仓库搜索 https://search.maven.org/
<dependency>
<groupId>com.starmcc</groupId>
<artifactId>qm-security</artifactId>
<version>1.1.0-RELEASE</version>
</dependency>
1
2
3
4
5
2
3
4
5
注意:需要servlet-api
、spring-web
、spring-webmvc
的支持,一般spring boot web
依赖会全部集成。
# Step.2 - 创建配置类
创建类
SecurityConfig
@Configuration
public class SecurityConfig implements WebMvcConfigurer {
@Autowired
private MyRealm myRealm;
/**
* 初始化QmSecurity安全框架
* 重写WebMvcConfigurer的addInterceptors方法
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// setTokenSecret 设置token加密秘钥
QmSecurityContent.setTokenSecret("shdioadnscoi21s90nbjio");
// 设置请求头和响应头中携带token的字段名 默认为token
QmSecurityContent.setHeaderTokenKeyName("token");
// 设置加密次数 默认2次
QmSecurityContent.setEncryptNumber(2);
// 设置自定义的realm (这里需要注意的是,自定义的realm如果需要spring注入内容请交由Spring管理)
QmSecurityContent.setRealm(myRealm);
// 设置排除URI校验集合
List<String> passUris = new ArrayList<>();
passUris.add("/upload/**");
passUris.add("/system/basic/**");
QmSecurityContent.setPassUris(passUris);
// 把框架添加到拦截器队列中,设置接管所有访问路径。
InterceptorRegistration interceptor = registry.addInterceptor(new QmSecurityInterceptor());
// 添加拦截路径
interceptor.addPathPatterns("/**");
// 设置拦截器的优先级
interceptor.order(2);
// 添加静态路径排除
interceptor.excludePathPatterns("/views/**");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Step.3 - 创建Realm
创建自定义的
MyRealm
并实现QmSecurityRealm
接口
@Component
public class MyRealm implements QmSecurityRealm {
@Override
public List<String> authorizationMatchingURI(QmUserInfo qmUserInfo) {
// 相关业务处理,并获取该用户的授权URI
List<String> list = new ArrayList<>();
list.add("/**");
return list;
}
@Override
public QmUserInfo authorizationUserInfo(QmUserInfo qmUserInfo, HttpServletRequest request, HttpServletResponse response) {
// 对该用户进行认证处理,如果返回空,则表示拦截该用户。
return qmUserInfo;
}
@Override
public void noPassCallBack(int type, HttpServletRequest request, HttpServletResponse response) throws Exception {
response.getWriter().print("安全检测不通过!");
}
@Override
public boolean verifyRestartToken(long tokenExpireTime, long signTime){
// 如果exp等于0表示该token永久不过期
if (tokenExpireTime <= 0) {
return false;
}
// 机制为 当前时间 是否小于 (签发时间 + 失效时长 / 2)
// 生成(签发时间 + 失效时长 / 2)的token过期时间
Date tokenExp = new Date(signTime + (tokenExpireTime * 1000 / 2));
if (System.currentTimeMillis() < tokenExp.getTime()) {
return false;
}
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Step.4 - 登录接口示例
使用
@QmPass
注解标注登录接口
/**
* 登录示例
* 增加该@QmPass注解表示该方法不校验登录和权限。
* @param username
* @param password
* @return
*/
@QmPass
@PostMapping("/login")
public String login(@QmBody String username, @QmBody String password) {
User user = userService.login(username, password);
if (user == null) {
// 登录失败
return super.sendJSON(QmCode._2, "登录失败!", null);
}
// 利用QmSecurityManager获取qmbject实例。
Qmbject qmbject = QmSecurityManager.getQmbject();
// 创建token签名信息QmUserInfo,并配置该对象的信息
QmUserInfo qmUserInfo = new QmUserInfo();
// identify为必须字段,用户唯一识别
qmUserInfo.setIdentify(user.getUserName());
// 设置用户缓存对象
qmUserInfo.setUser(JSON.toJSONString(user));
// 设置token失效时间 (秒) 10分钟token失效
qmUserInfo.setTokenExpireTime(60 * 10);
// 调用login方法,并设置他的过期时间,生成token
String token = null;
try {
token = qmbject.login(qmUserInfo);
} catch (QmSecurityQmUserInfoException e) {
// qmUserInfo参数异常
e.printStackTrace();
return super.sendJSON(QmCode._3, "qmUserInfo参数异常!", null);
} catch (QmSecurityCreateTokenException e) {
// 签发token时发生了异常
e.printStackTrace();
return super.sendJSON(QmCode._3, "签名时发生了异常!", null);
}
// 将token返回给前端
return super.sendJSON(QmCode._1, token);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# Step.5 - 进入开发
- 访问其他接口时,请求中的
header
附加token
参数。 token
校验失败,授权失败,URI授权失败,过期,都会直接被拦截,同时回调MyRealm
的noPassCallBack
方法,type
为对应的值。- 详细请参照Realm认证回调帮助文档
基础配置 →