88e030b7
王彪总
init project
|
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
# 权限验证阶段说明
## 阶段概述
权限验证阶段是网关调度的安全屏障,负责验证用户是否有访问特定资源的权限。通过IPrivilegeSMO接口实现多层次的权限校验机制,确保系统安全性。
## 核心组件
- **IPrivilegeSMO**: 权限校验接口
- **BootPrivilegeSMOImpl**: 权限校验实现类
- **IPageData**: 页面数据对象
- **RestTemplate**: REST调用模板
## 处理流程
### 1. 获取权限数据
- 通过AOP拦截器获取IPageData对象
- IPageData包含用户信息、token等认证数据
- 从请求上下文中获取权限验证所需信息
### 2. 权限校验调用
```java
// 调用权限校验服务
privilegeSMOImpl.hasPrivilege(restTemplate, pd, "/app/" + service);
```
### 3. 权限验证逻辑
- 验证用户与商户的关系权限
- 基于菜单权限配置进行访问控制
- 校验用户是否有访问该接口的权限
## 代码示例
### 权限校验接口定义
```java
public interface IPrivilegeSMO {
void hasPrivilege(RestTemplate restTemplate, IPageData pd, String resource);
}
```
### 权限校验实现类
```java
@Component
public class BootPrivilegeSMOImpl extends DefaultAbstractComponentSMO implements IPrivilegeSMO {
@Override
public void hasPrivilege(RestTemplate restTemplate, IPageData pd, String resource) {
// 调用父类的hasPrivilege方法进行权限验证
super.hasPrivilege(restTemplate, pd, resource);
}
}
```
### 在网关中的调用
```java
// 在AppController中调用权限校验
@RequestMapping(path = "/{service:.+}", method = RequestMethod.POST)
public ResponseEntity<String> servicePost(@PathVariable String service,
@RequestBody String postInfo,
HttpServletRequest request) {
// 初始化头信息...
Map<String, String> headers = new HashMap<>();
this.getRequestInfo(request, headers);
// 权限验证阶段
IPageData pd = (IPageData) request.getAttribute(CommonConstant.CONTEXT_PAGE_DATA);
privilegeSMOImpl.hasPrivilege(restTemplate, pd, "/app/" + service);
// 验证通过后进入服务分发阶段
ResponseEntity<String> responseEntity = apiSMOImpl.doApi(postInfo, headers, request);
return responseEntity;
}
```
## 关键配置
### 权限相关常量
```java
public final static String CONTEXT_PAGE_DATA = "pd"; // 页面数据上下文
public final static String COOKIE_AUTH_TOKEN = "_java110_token_"; // 认证token
```
### 资源路径格式
- 权限验证的资源路径格式:`/app/{service}`
- 与服务编码保持一致,便于权限管理
## 权限校验机制
### 1. 用户权限验证
- 验证用户身份和角色
- 检查用户是否属于当前商户
- 验证token有效性
### 2. 资源权限验证
- 基于RBAC(基于角色的访问控制)模型
- 验证用户是否有访问特定资源的权限
- 检查菜单权限配置
### 3. 业务权限验证
- 验证用户在当前业务上下文中的权限
- 检查数据权限范围
## 异常处理
### 权限异常类型
```java
// 权限校验失败时抛出异常
if (!hasPermission) {
throw new NoAuthorityException("用户没有访问权限");
}
```
### 统一异常处理
```java
try {
privilegeSMOImpl.hasPrivilege(restTemplate, pd, "/app/" + service);
} catch (NoAuthorityException e) {
logger.error("权限验证失败", e);
return ResultVo.error("权限不足", HttpStatus.FORBIDDEN);
}
```
## 技术要点
1. **AOP拦截机制**: 通过AOP自动获取IPageData对象
2. **继承复用**: BootPrivilegeSMOImpl继承DefaultAbstractComponentSMO复用权限逻辑
3. **统一资源标识**: 使用标准化的资源路径格式
4. **多层次验证**: 用户权限、资源权限、业务权限的多层次验证
## 安全特性
- 防止未授权访问
- 基于角色的细粒度权限控制
- 完整的权限审计日志
- 支持动态权限配置
|