# 权限验证阶段说明

## 阶段概述
权限验证阶段是网关调度的安全屏障，负责验证用户是否有访问特定资源的权限。通过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. **多层次验证**: 用户权限、资源权限、业务权限的多层次验证

## 安全特性
- 防止未授权访问
- 基于角色的细粒度权限控制
- 完整的权限审计日志
- 支持动态权限配置