298 lines
8.7 KiB
Markdown
298 lines
8.7 KiB
Markdown
|
|
# 安全指南
|
|||
|
|
|
|||
|
|
## 1. 安全概述
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目采用了全面的安全措施,确保系统的安全性和可靠性。本文档详细介绍了项目的安全措施和最佳实践。
|
|||
|
|
|
|||
|
|
## 2. 认证与授权
|
|||
|
|
|
|||
|
|
### 2.1 JWT 认证
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目使用 JWT(JSON Web Token)进行认证,确保用户身份的安全性。
|
|||
|
|
|
|||
|
|
**实现细节**:
|
|||
|
|
- 使用 Spring Security 实现 JWT 认证
|
|||
|
|
- 配置 JWT 密钥和过期时间
|
|||
|
|
- 验证 JWT 令牌的有效性
|
|||
|
|
|
|||
|
|
**配置示例**:
|
|||
|
|
```yaml
|
|||
|
|
spring:
|
|||
|
|
security:
|
|||
|
|
jwt:
|
|||
|
|
secret: your-secret-key
|
|||
|
|
expiration: 86400000
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2.2 角色授权
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目使用基于角色的访问控制(RBAC),确保用户只能访问其权限范围内的资源。
|
|||
|
|
|
|||
|
|
**预设角色**:
|
|||
|
|
- `ADMIN` - 全权
|
|||
|
|
- `MANAGER` - 运营主管
|
|||
|
|
- `OPERATOR` - 运营专员
|
|||
|
|
- `FINANCE` - 财务主管
|
|||
|
|
- `SOURCING` - 采购专家
|
|||
|
|
- `LOGISTICS` - 物流专家
|
|||
|
|
- `ANALYST` - 数据分析师
|
|||
|
|
|
|||
|
|
**授权实现**:
|
|||
|
|
- 使用 `@PreAuthorize` 注解进行方法级别的授权
|
|||
|
|
- 实现 `authorize()` 中间件进行路由级别的授权
|
|||
|
|
|
|||
|
|
**示例代码**:
|
|||
|
|
```java
|
|||
|
|
@PreAuthorize("hasRole('ADMIN')")
|
|||
|
|
public void deleteUser(Long id) {
|
|||
|
|
// 实现删除用户的逻辑
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 3. 数据安全
|
|||
|
|
|
|||
|
|
### 3.1 密码加密
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目使用 BCrypt 对用户密码进行加密,确保密码的安全性。
|
|||
|
|
|
|||
|
|
**实现细节**:
|
|||
|
|
- 使用 `BCryptPasswordEncoder` 对密码进行加密
|
|||
|
|
- 存储加密后的密码,不存储明文密码
|
|||
|
|
|
|||
|
|
**示例代码**:
|
|||
|
|
```java
|
|||
|
|
@Autowired
|
|||
|
|
private PasswordEncoder passwordEncoder;
|
|||
|
|
|
|||
|
|
public User createUser(User user) {
|
|||
|
|
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
|||
|
|
return userRepository.save(user);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.2 敏感数据保护
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目对敏感数据进行保护,确保数据的安全性。
|
|||
|
|
|
|||
|
|
**保护措施**:
|
|||
|
|
- 对敏感数据进行加密存储
|
|||
|
|
- 避免在日志中记录敏感信息
|
|||
|
|
- 使用 HTTPS 协议传输数据
|
|||
|
|
|
|||
|
|
**示例代码**:
|
|||
|
|
```java
|
|||
|
|
@Column(columnDefinition = "VARBINARY(255)")
|
|||
|
|
private byte[] sensitiveData;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 4. 输入验证
|
|||
|
|
|
|||
|
|
### 4.1 参数验证
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目对输入参数进行验证,确保输入的合法性。
|
|||
|
|
|
|||
|
|
**实现细节**:
|
|||
|
|
- 使用 `@Valid` 注解和 `BindingResult` 进行参数验证
|
|||
|
|
- 实现 `ValidationUtil` 工具类进行数据验证
|
|||
|
|
|
|||
|
|
**示例代码**:
|
|||
|
|
```java
|
|||
|
|
@PostMapping("/create")
|
|||
|
|
public ResponseEntity<User> createUser(@Valid @RequestBody User user, BindingResult bindingResult) {
|
|||
|
|
if (bindingResult.hasErrors()) {
|
|||
|
|
return ResponseEntity.badRequest().build();
|
|||
|
|
}
|
|||
|
|
return ResponseEntity.ok(userService.createUser(user));
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 SQL 注入防护
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目使用参数化查询,防止 SQL 注入攻击。
|
|||
|
|
|
|||
|
|
**实现细节**:
|
|||
|
|
- 使用 JPA 或 MyBatis 进行数据库操作
|
|||
|
|
- 避免直接拼接 SQL 语句
|
|||
|
|
|
|||
|
|
**示例代码**:
|
|||
|
|
```java
|
|||
|
|
// 正确的做法
|
|||
|
|
@Query("SELECT u FROM User u WHERE u.username = :username")
|
|||
|
|
User findByUsername(@Param("username") String username);
|
|||
|
|
|
|||
|
|
// 错误的做法(避免)
|
|||
|
|
String sql = "SELECT * FROM user WHERE username = '" + username + "'";
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 5. 跨站请求伪造(CSRF)防护
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目实现了 CSRF 防护,防止跨站请求伪造攻击。
|
|||
|
|
|
|||
|
|
**实现细节**:
|
|||
|
|
- 使用 Spring Security 的 CSRF 保护
|
|||
|
|
- 配置 CSRF 令牌的生成和验证
|
|||
|
|
|
|||
|
|
**配置示例**:
|
|||
|
|
```java
|
|||
|
|
@Configuration
|
|||
|
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
|
|
@Override
|
|||
|
|
protected void configure(HttpSecurity http) throws Exception {
|
|||
|
|
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 6. 速率限制
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目实现了速率限制,防止暴力破解和 DoS 攻击。
|
|||
|
|
|
|||
|
|
**实现细节**:
|
|||
|
|
- 实现 `RateLimitFilter` 过滤器
|
|||
|
|
- 基于客户端 IP 和请求 URI 进行限制
|
|||
|
|
- 限制客户端每分钟最大请求数为 60 次
|
|||
|
|
|
|||
|
|
**示例代码**:
|
|||
|
|
```java
|
|||
|
|
@Component
|
|||
|
|
public class RateLimitFilter implements Filter {
|
|||
|
|
private final Map<String, AtomicInteger> requestCounts = new ConcurrentHashMap<>();
|
|||
|
|
private final Map<String, Long> lastResetTimes = new ConcurrentHashMap<>();
|
|||
|
|
private static final int MAX_REQUESTS_PER_MINUTE = 60;
|
|||
|
|
|
|||
|
|
@Override
|
|||
|
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
|||
|
|
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
|||
|
|
String clientIp = httpRequest.getRemoteAddr();
|
|||
|
|
String requestUri = httpRequest.getRequestURI();
|
|||
|
|
String key = clientIp + ":" + requestUri;
|
|||
|
|
|
|||
|
|
long currentTime = System.currentTimeMillis();
|
|||
|
|
long lastResetTime = lastResetTimes.getOrDefault(key, 0L);
|
|||
|
|
|
|||
|
|
if (currentTime - lastResetTime > 60000) {
|
|||
|
|
requestCounts.put(key, new AtomicInteger(1));
|
|||
|
|
lastResetTimes.put(key, currentTime);
|
|||
|
|
} else {
|
|||
|
|
AtomicInteger count = requestCounts.get(key);
|
|||
|
|
if (count != null && count.incrementAndGet() > MAX_REQUESTS_PER_MINUTE) {
|
|||
|
|
((HttpServletResponse) response).setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
chain.doFilter(request, response);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 7. 安全日志
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目实现了安全日志,记录系统的安全事件。
|
|||
|
|
|
|||
|
|
**实现细节**:
|
|||
|
|
- 使用 Logback 配置安全日志
|
|||
|
|
- 记录用户登录、登出、权限变更等安全事件
|
|||
|
|
- 记录异常登录尝试和权限错误
|
|||
|
|
|
|||
|
|
**配置示例**:
|
|||
|
|
```xml
|
|||
|
|
<appender name="SECURITY" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
|||
|
|
<file>logs/security.log</file>
|
|||
|
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
|||
|
|
<fileNamePattern>logs/security.%d{yyyy-MM-dd}.log</fileNamePattern>
|
|||
|
|
<maxHistory>30</maxHistory>
|
|||
|
|
</rollingPolicy>
|
|||
|
|
<encoder>
|
|||
|
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
|||
|
|
</encoder>
|
|||
|
|
</appender>
|
|||
|
|
|
|||
|
|
<logger name="com.crawlful.hub.security" level="INFO" additivity="false">
|
|||
|
|
<appender-ref ref="SECURITY" />
|
|||
|
|
</logger>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 8. 安全最佳实践
|
|||
|
|
|
|||
|
|
### 8.1 代码安全
|
|||
|
|
|
|||
|
|
- **使用最新的依赖**:定期更新项目依赖,修复安全漏洞
|
|||
|
|
- **避免硬编码**:避免在代码中硬编码密钥、密码等敏感信息
|
|||
|
|
- **使用安全的加密算法**:使用强加密算法,如 BCrypt、AES 等
|
|||
|
|
- **定期代码审查**:定期进行代码审查,发现和修复安全问题
|
|||
|
|
|
|||
|
|
### 8.2 服务器安全
|
|||
|
|
|
|||
|
|
- **使用 HTTPS**:使用 HTTPS 协议传输数据
|
|||
|
|
- **限制访问**:限制服务器的访问范围,只允许必要的端口和 IP 访问
|
|||
|
|
- **定期更新**:定期更新服务器操作系统和软件,修复安全漏洞
|
|||
|
|
- **使用防火墙**:使用防火墙保护服务器,防止未授权访问
|
|||
|
|
|
|||
|
|
### 8.3 数据库安全
|
|||
|
|
|
|||
|
|
- **最小权限原则**:只授予数据库用户必要的权限
|
|||
|
|
- **定期备份**:定期备份数据库,防止数据丢失
|
|||
|
|
- **使用参数化查询**:防止 SQL 注入攻击
|
|||
|
|
- **加密敏感数据**:对敏感数据进行加密存储
|
|||
|
|
|
|||
|
|
### 8.4 应用安全
|
|||
|
|
|
|||
|
|
- **使用 CSRF 保护**:防止跨站请求伪造攻击
|
|||
|
|
- **实现速率限制**:防止暴力破解和 DoS 攻击
|
|||
|
|
- **验证输入**:对所有输入进行验证,防止恶意输入
|
|||
|
|
- **使用安全的会话管理**:使用安全的会话管理机制,防止会话劫持
|
|||
|
|
|
|||
|
|
## 9. 安全审计
|
|||
|
|
|
|||
|
|
### 9.1 审计日志
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目实现了审计日志,记录系统的操作和事件。
|
|||
|
|
|
|||
|
|
**实现细节**:
|
|||
|
|
- 使用 `cf_audit` 表存储审计日志
|
|||
|
|
- 记录用户操作、资源访问、权限变更等事件
|
|||
|
|
- 记录 IP 地址、用户代理等信息
|
|||
|
|
|
|||
|
|
**示例代码**:
|
|||
|
|
```java
|
|||
|
|
@Service
|
|||
|
|
public class AuditService {
|
|||
|
|
@Autowired
|
|||
|
|
private AuditRepository auditRepository;
|
|||
|
|
|
|||
|
|
public void logAudit(String tenantId, String shopId, Long userId, String action, String resourceType, String resourceId, String ipAddress, String userAgent, String details) {
|
|||
|
|
Audit audit = new Audit();
|
|||
|
|
audit.setTenantId(tenantId);
|
|||
|
|
audit.setShopId(shopId);
|
|||
|
|
audit.setUserId(userId);
|
|||
|
|
audit.setAction(action);
|
|||
|
|
audit.setResourceType(resourceType);
|
|||
|
|
audit.setResourceId(resourceId);
|
|||
|
|
audit.setIpAddress(ipAddress);
|
|||
|
|
audit.setUserAgent(userAgent);
|
|||
|
|
audit.setDetails(details);
|
|||
|
|
audit.setCreatedAt(new Date());
|
|||
|
|
auditRepository.save(audit);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 9.2 安全扫描
|
|||
|
|
|
|||
|
|
Crawlful Hub 项目定期进行安全扫描,发现和修复安全漏洞。
|
|||
|
|
|
|||
|
|
**扫描工具**:
|
|||
|
|
- **OWASP ZAP**:用于 Web 应用安全扫描
|
|||
|
|
- **SonarQube**:用于代码安全扫描
|
|||
|
|
- **Nmap**:用于网络安全扫描
|
|||
|
|
|
|||
|
|
**扫描频率**:
|
|||
|
|
- 开发环境:每次代码提交后
|
|||
|
|
- 测试环境:每周一次
|
|||
|
|
- 生产环境:每月一次
|
|||
|
|
|
|||
|
|
## 10. 总结
|
|||
|
|
|
|||
|
|
本安全指南详细介绍了 Crawlful Hub 项目的安全措施和最佳实践。通过本指南,您可以了解如何确保系统的安全性和可靠性。
|