11 KiB
安全机制
**本文档中引用的文件** - [User.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/dal/entity/User.java) - [SecurityConfiguration.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/security/SecurityConfiguration.java) - [JwtAuthenticationToken.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/security/auth/JwtAuthenticationToken.java) - [AbstractJwtAuthenticationToken.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/security/auth/AbstractJwtAuthenticationToken.java) - [JCPPErrorResponseHandler.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/exception/JCPPErrorResponseHandler.java) - [RestAuthenticationProvider.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/security/auth/rest/RestAuthenticationProvider.java) - [JwtAuthenticationProvider.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/security/auth/jwt/JwtAuthenticationProvider.java) - [UserCredentials.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/service/security/model/UserCredentials.java) - [AuthorityEnum.java](file://jcpp-app/src/main/java/sanbing/jcpp/app/dal/config/ibatis/enums/AuthorityEnum.java) - [NoXss.java](file://jcpp-infrastructure-util/src/main/java/sanbing/jcpp/infrastructure/util/validation/NoXss.java)目录
简介
JChargePointProtocol(JCPP)系统实现了一套完整的安全机制,基于JWT(JSON Web Token)进行身份认证和授权。系统通过多层安全防护,包括基于角色的访问控制、密码加密存储、输入验证和异常处理,确保充电桩管理平台的安全性。本文档详细说明系统的安全架构和实现细节。
JWT认证流程
JCPP系统采用基于JWT的无状态认证机制,包含Access Token和Refresh Token两种令牌,实现安全的用户会话管理。
认证流程概述
sequenceDiagram
participant 用户
participant UserController
participant RestAuthenticationProvider
participant UserService
participant JwtTokenFactory
用户->>UserController : 提交用户名和密码
UserController->>RestAuthenticationProvider : 创建认证请求
RestAuthenticationProvider->>UserService : 验证用户凭证
UserService-->>RestAuthenticationProvider : 返回用户信息
RestAuthenticationProvider->>JwtTokenFactory : 生成JWT令牌对
JwtTokenFactory-->>RestAuthenticationProvider : 返回Access和Refresh令牌
RestAuthenticationProvider-->>UserController : 返回认证结果
UserController-->>用户 : 返回包含令牌的响应
Diagram sources
Section sources
Access Token和Refresh Token生成
当用户成功登录时,系统生成一对JWT令牌:
- Access Token:短期有效的访问令牌,用于后续API请求的身份验证
- Refresh Token:长期有效的刷新令牌,用于获取新的Access Token
令牌中包含用户信息和权限,通过JwtTokenFactory组件生成,确保令牌的安全性和完整性。
JwtAuthenticationToken身份验证
后续请求通过JwtAuthenticationToken进行身份验证。系统使用JwtTokenAuthenticationProcessingFilter
拦截请求,从请求头或查询参数中提取JWT令牌,并通过JwtAuthenticationProvider验证令牌的有效性。
classDiagram
class AbstractJwtAuthenticationToken {
-RawAccessJwtToken rawAccessToken
-SecurityUser securityUser
+AbstractJwtAuthenticationToken(RawAccessJwtToken)
+AbstractJwtAuthenticationToken(SecurityUser)
+getCredentials()
+getPrincipal()
+eraseCredentials()
}
class JwtAuthenticationToken {
+JwtAuthenticationToken(RawAccessJwtToken)
+JwtAuthenticationToken(SecurityUser)
}
AbstractJwtAuthenticationToken <|-- JwtAuthenticationToken
AbstractJwtAuthenticationToken --> RawAccessJwtToken : "包含"
AbstractJwtAuthenticationToken --> SecurityUser : "包含"
Diagram sources
Section sources
安全配置
URL路径访问权限控制
SecurityConfiguration类定义了系统的安全策略,通过Spring Security配置不同URL路径的访问权限:
flowchart TD
A[所有请求] --> B{路径匹配}
B --> |/index.html, /assets/**, /static/**, /api/noauth/**, /api/license/**, /test/**| C[允许访问]
B --> |/api/auth/login| D[允许访问]
B --> |/api/auth/token| E[允许访问]
B --> |/api/ws/**| F[允许访问]
B --> |/api/**| G[需要认证]
G --> H[通过JWT验证]
H --> I[授权访问]
Diagram sources
Section sources
AuthorityEnum权限控制
系统通过AuthorityEnum枚举定义用户权限级别:
classDiagram
class AuthorityEnum {
+SYS_ADMIN
+REFRESH_TOKEN
+parse(String)
+getValue()
}
class User {
-AuthorityEnum authority
}
class SecurityUser {
-AuthorityEnum authority
}
User --> AuthorityEnum : "拥有"
SecurityUser --> AuthorityEnum : "拥有"
Diagram sources
Section sources
JWT令牌解析和验证
系统支持多种方式传递JWT令牌:
- 请求头
X-Authorization - 请求头
Authorization - 查询参数
token
JwtTokenAuthenticationProcessingFilter负责提取和验证令牌,确保只有有效的令牌才能访问受保护的API端点。
异常处理机制
JCPPErrorResponseHandler异常处理
JCPPErrorResponseHandler是系统的核心异常处理器,负责将各种业务异常转换为标准化的HTTP响应:
flowchart TD
A[异常发生] --> B{异常类型}
B --> |JCPPException| C[根据ErrorCode映射HTTP状态码]
B --> |AccessDeniedException| D[返回403 Forbidden]
B --> |AuthenticationException| E[返回401 Unauthorized]
B --> |DataAccessException| F[返回500 Internal Server Error]
B --> |其他异常| G[返回500 Internal Server Error]
C --> H[生成JCPPErrorResponse]
D --> H
E --> H
F --> H
G --> H
H --> I[返回JSON格式错误响应]
Diagram sources
Section sources
ErrorCode标准化
系统定义了统一的ErrorCode枚举,确保错误信息的一致性:
| 错误码 | HTTP状态码 | 描述 |
|---|---|---|
| GENERAL | 500 | 通用错误 |
| AUTHENTICATION | 401 | 认证失败 |
| JWT_TOKEN_EXPIRED | 401 | 令牌已过期 |
| CREDENTIALS_EXPIRED | 401 | 凭证已过期 |
| PERMISSION_DENIED | 403 | 权限不足 |
| BAD_REQUEST_PARAMS | 400 | 请求参数错误 |
| ITEM_NOT_FOUND | 404 | 项目未找到 |
Section sources
安全最佳实践
密码加密存储
系统使用BCryptPasswordEncoder对用户密码进行加密存储,确保即使数据库泄露,攻击者也无法轻易获取明文密码。
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
Section sources
防止XSS攻击
系统通过@NoXss注解防止跨站脚本攻击(XSS),对用户输入进行严格验证:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = NoXssValidator.class)
public @interface NoXss {
String message() default "Input contains XSS attack patterns";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Section sources
敏感信息脱敏
系统对敏感信息进行脱敏处理,确保日志和响应中不包含完整的敏感数据。UserCredentials类中的密码字段在日志输出时会被自动脱敏。
@Data
@ToString(callSuper = true)
public class UserCredentials {
private boolean enabled;
private String password;
private String activateToken;
// 其他字段...
}
Section sources
安全审计日志
系统通过SLF4J和Log4j2框架记录安全相关的审计日志,包括:
- 用户登录成功/失败事件
- 权限访问拒绝事件
- 异常处理事件
- 数据库访问事件
日志记录在JCPPErrorResponseHandler和相关安全组件中实现,确保所有安全相关事件都有迹可循。
@Slf4j
@Controller
@RestControllerAdvice
public class JCPPErrorResponseHandler extends ResponseEntityExceptionHandler implements AccessDeniedHandler, ErrorController {
// 日志记录实现
}
Section sources