ai-engineering-init 1.7.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/.claude/agents/bug-analyzer.md +103 -0
  2. package/.claude/agents/code-reviewer.md +115 -5
  3. package/.claude/agents/image-reader.md +154 -0
  4. package/.claude/agents/loki-runner.md +80 -0
  5. package/.claude/agents/mysql-runner.md +81 -0
  6. package/.claude/agents/requirements-analyzer.md +162 -0
  7. package/.claude/agents/task-fetcher.md +75 -0
  8. package/.claude/commands/dev.md +29 -0
  9. package/.claude/commands/next.md +31 -1
  10. package/.claude/commands/progress.md +23 -1
  11. package/.claude/hooks/skill-forced-eval.js +46 -62
  12. package/.claude/settings.json +10 -1
  13. package/.claude/skills/api-development/SKILL.md +179 -130
  14. package/.claude/skills/architecture-design/SKILL.md +102 -212
  15. package/.claude/skills/backend-annotations/SKILL.md +166 -220
  16. package/.claude/skills/bug-detective/SKILL.md +225 -186
  17. package/.claude/skills/code-patterns/SKILL.md +127 -244
  18. package/.claude/skills/collaborating-with-codex/SKILL.md +96 -113
  19. package/.claude/skills/crud-development/SKILL.md +226 -307
  20. package/.claude/skills/data-permission/SKILL.md +131 -202
  21. package/.claude/skills/database-ops/SKILL.md +158 -355
  22. package/.claude/skills/error-handler/SKILL.md +224 -285
  23. package/.claude/skills/file-oss-management/SKILL.md +174 -169
  24. package/.claude/skills/git-workflow/SKILL.md +123 -341
  25. package/.claude/skills/json-serialization/SKILL.md +121 -137
  26. package/.claude/skills/performance-doctor/SKILL.md +83 -89
  27. package/.claude/skills/redis-cache/SKILL.md +134 -185
  28. package/.claude/skills/scheduled-jobs/SKILL.md +187 -224
  29. package/.claude/skills/security-guard/SKILL.md +168 -276
  30. package/.claude/skills/sms-mail/SKILL.md +266 -228
  31. package/.claude/skills/social-login/SKILL.md +257 -195
  32. package/.claude/skills/tenant-management/SKILL.md +172 -188
  33. package/.claude/skills/utils-toolkit/SKILL.md +214 -222
  34. package/.claude/skills/websocket-sse/SKILL.md +251 -172
  35. package/.claude/skills/workflow-engine/SKILL.md +178 -250
  36. package/.codex/skills/api-development/SKILL.md +179 -130
  37. package/.codex/skills/architecture-design/SKILL.md +102 -212
  38. package/.codex/skills/backend-annotations/SKILL.md +166 -220
  39. package/.codex/skills/bug-detective/SKILL.md +225 -186
  40. package/.codex/skills/code-patterns/SKILL.md +127 -244
  41. package/.codex/skills/collaborating-with-codex/SKILL.md +96 -113
  42. package/.codex/skills/crud-development/SKILL.md +226 -307
  43. package/.codex/skills/data-permission/SKILL.md +131 -202
  44. package/.codex/skills/database-ops/SKILL.md +158 -355
  45. package/.codex/skills/dev/SKILL.md +476 -131
  46. package/.codex/skills/error-handler/SKILL.md +224 -285
  47. package/.codex/skills/file-oss-management/SKILL.md +174 -169
  48. package/.codex/skills/git-workflow/SKILL.md +123 -341
  49. package/.codex/skills/json-serialization/SKILL.md +121 -137
  50. package/.codex/skills/next/SKILL.md +186 -42
  51. package/.codex/skills/performance-doctor/SKILL.md +83 -89
  52. package/.codex/skills/progress/SKILL.md +147 -76
  53. package/.codex/skills/redis-cache/SKILL.md +134 -185
  54. package/.codex/skills/scheduled-jobs/SKILL.md +187 -224
  55. package/.codex/skills/security-guard/SKILL.md +168 -276
  56. package/.codex/skills/sms-mail/SKILL.md +266 -228
  57. package/.codex/skills/social-login/SKILL.md +257 -195
  58. package/.codex/skills/tenant-management/SKILL.md +172 -188
  59. package/.codex/skills/utils-toolkit/SKILL.md +214 -222
  60. package/.codex/skills/websocket-sse/SKILL.md +251 -172
  61. package/.codex/skills/workflow-engine/SKILL.md +178 -250
  62. package/.cursor/agents/bug-analyzer.md +102 -0
  63. package/.cursor/agents/code-reviewer.md +80 -97
  64. package/.cursor/agents/image-reader.md +154 -0
  65. package/.cursor/agents/loki-runner.md +80 -0
  66. package/.cursor/agents/mysql-runner.md +81 -0
  67. package/.cursor/agents/project-manager.md +1 -1
  68. package/.cursor/agents/requirements-analyzer.md +141 -0
  69. package/.cursor/agents/task-fetcher.md +75 -0
  70. package/.cursor/hooks/cursor-skill-eval.js +66 -6
  71. package/.cursor/skills/api-development/SKILL.md +179 -130
  72. package/.cursor/skills/architecture-design/SKILL.md +102 -212
  73. package/.cursor/skills/backend-annotations/SKILL.md +166 -220
  74. package/.cursor/skills/bug-detective/SKILL.md +225 -186
  75. package/.cursor/skills/code-patterns/SKILL.md +127 -244
  76. package/.cursor/skills/collaborating-with-codex/SKILL.md +96 -113
  77. package/.cursor/skills/crud-development/SKILL.md +226 -307
  78. package/.cursor/skills/data-permission/SKILL.md +131 -202
  79. package/.cursor/skills/database-ops/SKILL.md +158 -355
  80. package/.cursor/skills/error-handler/SKILL.md +224 -285
  81. package/.cursor/skills/file-oss-management/SKILL.md +174 -169
  82. package/.cursor/skills/git-workflow/SKILL.md +123 -341
  83. package/.cursor/skills/json-serialization/SKILL.md +121 -137
  84. package/.cursor/skills/performance-doctor/SKILL.md +83 -89
  85. package/.cursor/skills/redis-cache/SKILL.md +134 -185
  86. package/.cursor/skills/scheduled-jobs/SKILL.md +187 -224
  87. package/.cursor/skills/security-guard/SKILL.md +168 -276
  88. package/.cursor/skills/sms-mail/SKILL.md +266 -228
  89. package/.cursor/skills/social-login/SKILL.md +257 -195
  90. package/.cursor/skills/tenant-management/SKILL.md +172 -188
  91. package/.cursor/skills/utils-toolkit/SKILL.md +214 -222
  92. package/.cursor/skills/websocket-sse/SKILL.md +251 -172
  93. package/.cursor/skills/workflow-engine/SKILL.md +178 -250
  94. package/AGENTS.md +117 -540
  95. package/CLAUDE.md +105 -117
  96. package/README.md +37 -6
  97. package/bin/index.js +5 -1
  98. package/package.json +1 -1
  99. package/src/skills/api-development/SKILL.md +179 -130
  100. package/src/skills/architecture-design/SKILL.md +102 -212
  101. package/src/skills/backend-annotations/SKILL.md +166 -220
  102. package/src/skills/bug-detective/SKILL.md +225 -186
  103. package/src/skills/code-patterns/SKILL.md +127 -244
  104. package/src/skills/collaborating-with-codex/SKILL.md +96 -113
  105. package/src/skills/crud-development/SKILL.md +226 -307
  106. package/src/skills/data-permission/SKILL.md +131 -202
  107. package/src/skills/database-ops/SKILL.md +158 -355
  108. package/src/skills/error-handler/SKILL.md +224 -285
  109. package/src/skills/file-oss-management/SKILL.md +174 -169
  110. package/src/skills/git-workflow/SKILL.md +123 -341
  111. package/src/skills/json-serialization/SKILL.md +121 -137
  112. package/src/skills/performance-doctor/SKILL.md +83 -89
  113. package/src/skills/redis-cache/SKILL.md +134 -185
  114. package/src/skills/scheduled-jobs/SKILL.md +187 -224
  115. package/src/skills/security-guard/SKILL.md +168 -276
  116. package/src/skills/sms-mail/SKILL.md +266 -228
  117. package/src/skills/social-login/SKILL.md +257 -195
  118. package/src/skills/tenant-management/SKILL.md +172 -188
  119. package/src/skills/utils-toolkit/SKILL.md +214 -222
  120. package/src/skills/websocket-sse/SKILL.md +251 -172
  121. package/src/skills/workflow-engine/SKILL.md +178 -250
  122. package/.claude/skills/skill-creator/LICENSE.txt +0 -202
  123. package/.claude/skills/skill-creator/SKILL.md +0 -479
  124. package/.claude/skills/skill-creator/agents/analyzer.md +0 -274
  125. package/.claude/skills/skill-creator/agents/comparator.md +0 -202
  126. package/.claude/skills/skill-creator/agents/grader.md +0 -223
  127. package/.claude/skills/skill-creator/assets/eval_review.html +0 -146
  128. package/.claude/skills/skill-creator/eval-viewer/generate_review.py +0 -471
  129. package/.claude/skills/skill-creator/eval-viewer/viewer.html +0 -1325
  130. package/.claude/skills/skill-creator/references/schemas.md +0 -430
  131. package/.claude/skills/skill-creator/scripts/__init__.py +0 -0
  132. package/.claude/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
  133. package/.claude/skills/skill-creator/scripts/generate_report.py +0 -326
  134. package/.claude/skills/skill-creator/scripts/improve_description.py +0 -248
  135. package/.claude/skills/skill-creator/scripts/package_skill.py +0 -136
  136. package/.claude/skills/skill-creator/scripts/quick_validate.py +0 -103
  137. package/.claude/skills/skill-creator/scripts/run_eval.py +0 -310
  138. package/.claude/skills/skill-creator/scripts/run_loop.py +0 -332
  139. package/.claude/skills/skill-creator/scripts/utils.py +0 -47
@@ -1,353 +1,245 @@
1
1
  ---
2
2
  name: security-guard
3
3
  description: |
4
- 后端安全开发规范。包含 Sa-Token 认证授权、数据脱敏、数据加密、接口安全、漏洞防护。
5
-
4
+ 通用后端安全开发指南。包含认证授权模式对比、输入校验、XSS/SQL注入防护、数据脱敏加密、安全检查清单。
6
5
  触发场景:
7
- - Sa-Token 权限控制配置
8
- - 登录认证、Token 管理
9
- - 数据脱敏处理(@Sensitive)
10
- - 数据加密处理(@EncryptField、@ApiEncrypt)
11
- - 接口限流(@RateLimiter)
12
- - 防重复提交(@RepeatSubmit)
13
- - XSS/SQL注入防护
14
-
15
- 触发词:安全、Sa-Token、@SaCheckPermission、@SaCheckLogin、@SaCheckRole、登录认证、Token、数据脱敏、@Sensitive、加密解密、@EncryptField、@ApiEncrypt、限流、@RateLimiter、防重复、@RepeatSubmit、XSS、SQL注入、漏洞防护、敏感数据、LoginHelper
16
-
17
- 注意:
18
- - 如需行级数据权限(@DataPermission、部门隔离),请使用 data-permission。
19
- - 如果是设计异常处理机制(try-catch、错误码),请使用 error-handler。
6
+ - 设计认证授权方案
7
+ - 配置权限校验
8
+ - 防护 XSS / SQL 注入
9
+ - 数据脱敏 / 加密处理
10
+ - 安全合规审查
11
+ 触发词:安全、认证、授权、权限、Token、登录、XSS、SQL注入、脱敏、加密、RBAC、OAuth、CORS、漏洞防护
12
+ 注意:如果项目有专属技能(如 `leniu-security-guard`),优先使用专属版本。
20
13
  ---
21
14
 
22
- # 后端安全开发指南
23
-
24
- > 本项目是纯后端项目,本文档专注于 Java 后端安全规范。
25
-
26
- ## 1. Sa-Token 认证授权
27
-
28
- ### 1.1 权限注解
29
-
30
- ```java
31
- import cn.dev33.satoken.annotation.*;
32
-
33
- @SaCheckLogin // 登录校验
34
- @SaCheckPermission("system:user:add") // 权限校验
35
- @SaCheckRole("admin") // 角色校验
36
- @SaCheckSafe // 二级认证(敏感操作)
37
-
38
- // 多权限(满足其一 / 全部满足)
39
- @SaCheckPermission(value = {"system:user:add", "system:user:update"}, mode = SaMode.OR)
40
- @SaCheckPermission(value = {"system:user:add", "system:user:update"}, mode = SaMode.AND)
41
-
42
- // 多角色(满足其一)
43
- @SaCheckRole(value = {"admin", "editor"}, mode = SaMode.OR)
44
- ```
45
-
46
- ### 1.2 LoginHelper 工具类
47
-
48
- > 位置:`ruoyi-common-satoken/.../utils/LoginHelper.java`
15
+ # 安全开发指南
49
16
 
50
- ```java
51
- import org.dromara.common.satoken.utils.LoginHelper;
52
-
53
- // 用户信息
54
- LoginUser user = LoginHelper.getLoginUser();
55
- Long userId = LoginHelper.getUserId();
56
- String name = LoginHelper.getUsername();
57
- String tenant = LoginHelper.getTenantId();
58
- Long deptId = LoginHelper.getDeptId();
59
-
60
- // 管理员判断
61
- LoginHelper.isSuperAdmin(); // userId = 1
62
- LoginHelper.isTenantAdmin(); // 租户管理员
63
- LoginHelper.isLogin(); // 是否已登录
64
-
65
- // 用户类型 & 登录
66
- UserType type = LoginHelper.getUserType();
67
- LoginHelper.login(loginUser, loginParameter);
68
- ```
17
+ > 通用模板。如果项目有专属技能(如 `leniu-security-guard`),优先使用。
69
18
 
70
- ### 1.3 角色与权限常量
19
+ ## 设计原则
71
20
 
72
- | 常量 | 值 | 说明 |
73
- |------|-----|------|
74
- | 超级管理员角色 | `superadmin` | 拥有所有权限 |
75
- | 租户管理员角色 | `admin` | 租户内所有权限 |
76
- | 通配符权限 | `*:*:*` | 所有权限标识 |
77
- | 超级管理员ID | `1L` | 系统超管用户ID |
21
+ 1. **纵深防御**:不依赖单一安全机制,从传输层、认证层、授权层、数据层多维度防护。
22
+ 2. **最小权限**:默认拒绝,显式授权。每个接口必须声明所需权限。
23
+ 3. **输入不可信**:所有外部输入(用户参数、请求头、Cookie)必须校验后使用。
24
+ 4. **敏感数据保护**:存储加密、传输加密、展示脱敏,三层保护。
25
+ 5. **审计可追溯**:关键操作记录日志,包含操作人、操作时间、操作内容。
78
26
 
79
27
  ---
80
28
 
81
- ## 2. 数据脱敏(@Sensitive)
82
-
83
- > 位置:`ruoyi-common-sensitive/.../`
84
- > 完整 17 种策略详见 `references/sensitive-strategies.md`
85
-
86
- ### 基本用法
87
-
88
- ```java
89
- import org.dromara.common.sensitive.annotation.Sensitive;
90
- import org.dromara.common.sensitive.core.SensitiveStrategy;
91
-
92
- public class UserVo {
93
- @Sensitive(strategy = SensitiveStrategy.PHONE) // 138****8888
94
- private String phone;
95
-
96
- @Sensitive(strategy = SensitiveStrategy.ID_CARD) // 110***********1234
97
- private String idCard;
98
-
99
- @Sensitive(strategy = SensitiveStrategy.EMAIL) // t**@example.com
100
- private String email;
101
-
102
- @Sensitive(strategy = SensitiveStrategy.BANK_CARD) // 6222***********1234
103
- private String bankCard;
29
+ ## 认证授权方案对比
104
30
 
105
- @Sensitive(strategy = SensitiveStrategy.CHINESE_NAME) // 张*
106
- private String realName;
107
-
108
- @Sensitive(strategy = SensitiveStrategy.PASSWORD) // ******
109
- private String password;
110
- }
111
- ```
112
-
113
- ### 基于角色/权限的脱敏控制
114
-
115
- ```java
116
- // admin 角色可查看原数据,其他用户看脱敏数据
117
- @Sensitive(strategy = SensitiveStrategy.ID_CARD, roleKey = {"admin"})
118
- private String idCard;
119
-
120
- // 需要权限才能看原数据
121
- @Sensitive(strategy = SensitiveStrategy.PHONE, perms = {"system:user:detail"})
122
- private String phone;
123
-
124
- // roleKey 和 perms 是 OR 关系
125
- @Sensitive(strategy = SensitiveStrategy.BANK_CARD,
126
- roleKey = {"admin"}, perms = {"finance:account:query"})
127
- private String bankCard;
128
- ```
129
-
130
- ### 日志脱敏
131
-
132
- ```java
133
- // NG: log.info("手机号: {}", phone);
134
- // OK:
135
- log.info("手机号: {}", DesensitizedUtil.mobilePhone(phone));
136
- ```
31
+ | 维度 | Spring Security | Apache Shiro | Sa-Token |
32
+ |------|----------------|-------------|----------|
33
+ | 学习曲线 | 陡峭 | 中等 | 平缓 |
34
+ | 功能丰富度 | 最全面 | 基础够用 | 功能丰富 |
35
+ | Spring 集成 | 原生集成 | 需适配 | 自动配置 |
36
+ | OAuth2 支持 | 原生支持 | 需扩展 | 内置 SSO |
37
+ | 微服务支持 | 优秀 | 一般 | 良好 |
38
+ | 适用场景 | 企业级、复杂权限 | 轻量项目 | 快速开发 |
137
39
 
138
40
  ---
139
41
 
140
- ## 3. 数据加密(@EncryptField / @ApiEncrypt)
141
-
142
- > 位置:`ruoyi-common-encrypt/.../`
143
- > 完整加密配置和工具类详见 `references/encrypt-config.md`
42
+ ## 实现模式
144
43
 
145
- ### 支持算法
146
-
147
- | 算法 | 类型 | 密钥要求 |
148
- |------|------|---------|
149
- | BASE64 | 编码 | 无 |
150
- | AES | 对称加密 | 16/24/32 位 |
151
- | RSA | 非对称加密 | 公钥/私钥 |
152
- | SM2 | 国密非对称 | 公钥/私钥 |
153
- | SM4 | 国密对称 | 16 位 |
154
-
155
- ### 字段级加密
44
+ ### 1. 认证(Authentication)
156
45
 
157
46
  ```java
158
- import org.dromara.common.encrypt.annotation.EncryptField;
159
- import org.dromara.common.encrypt.enumd.AlgorithmType;
160
-
161
- public class User {
162
- @EncryptField // 默认(全局配置)
163
- private String password;
164
-
165
- @EncryptField(algorithm = AlgorithmType.AES) // AES
166
- private String idCard;
167
-
168
- @EncryptField(algorithm = AlgorithmType.SM4) // SM4 国密
169
- private String phone;
47
+ // 方式一:注解式认证(框架无关的概念)
48
+ @[你的认证注解] // 登录校验
49
+ @[你的权限注解]("system:user:add") // 权限校验
50
+ @[你的角色注解]("admin") // 角色校验
51
+
52
+ // 方式二:编程式认证
53
+ @RestController
54
+ public class UserController {
55
+
56
+ @Autowired
57
+ private [你的安全工具类] securityUtils;
58
+
59
+ @GetMapping("/profile")
60
+ public Result<?> profile() {
61
+ // 获取当前登录用户
62
+ Long userId = securityUtils.getCurrentUserId();
63
+ String username = securityUtils.getCurrentUsername();
64
+ boolean isAdmin = securityUtils.hasRole("admin");
65
+ boolean hasPerm = securityUtils.hasPermission("system:user:list");
66
+
67
+ if (!securityUtils.isAuthenticated()) {
68
+ throw new [你的异常类]("未登录");
69
+ }
70
+ // ...
71
+ }
170
72
  }
171
73
  ```
172
74
 
173
- ### API 级加密
75
+ ### 2. 授权模型(RBAC)
174
76
 
175
- ```java
176
- import org.dromara.common.encrypt.annotation.ApiEncrypt;
177
-
178
- @ApiEncrypt // 请求体自动解密
179
- @PostMapping("/addUser")
180
- public R<Long> addUser(@RequestBody UserBo bo) { }
181
-
182
- @ApiEncrypt(response = true) // 请求解密 + 响应加密
183
- @PostMapping("/updateUser")
184
- public R<Void> updateUser(@RequestBody UserBo bo) { }
185
77
  ```
78
+ 用户 (User)
79
+ └── 角色 (Role) -- 多对多
80
+ └── 权限 (Permission) -- 多对多
81
+ └── 菜单/按钮/API
186
82
 
187
- ---
188
-
189
- ## 4. 接口限流(@RateLimiter)
190
-
191
- > 位置:`ruoyi-common-ratelimiter/.../`
83
+ 权限标识格式:模块:资源:操作
84
+ 示例:system:user:add, order:info:export
85
+ ```
192
86
 
193
87
  ```java
194
- import org.dromara.common.ratelimiter.annotation.RateLimiter;
195
- import org.dromara.common.ratelimiter.enums.LimitType;
196
-
197
- // 全局限流:60秒内最多100次
198
- @RateLimiter(time = 60, count = 100)
199
-
200
- // IP 限流:每个 IP 每分钟最多10次
201
- @RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
202
-
203
- // 动态 key(SpEL)
204
- @RateLimiter(key = "#userId", time = 60, count = 5)
205
-
206
- // 自定义错误消息
207
- @RateLimiter(time = 60, count = 10, message = "访问过于频繁,请稍后再试")
88
+ // 多权限校验(满足其一 / 全部满足)
89
+ @RequiresPermissions(value = {"system:user:add", "system:user:edit"}, logical = Logical.OR)
90
+ @RequiresPermissions(value = {"system:user:add", "system:user:edit"}, logical = Logical.AND)
208
91
 
209
- // 集群限流
210
- @RateLimiter(time = 60, count = 1000, limitType = LimitType.CLUSTER)
92
+ // 多角色校验
93
+ @RequiresRoles(value = {"admin", "editor"}, logical = Logical.OR)
211
94
  ```
212
95
 
213
- ### 推荐配置
214
-
215
- | 场景 | time | count | limitType |
216
- |------|------|-------|-----------|
217
- | 登录接口 | 60 | 5-10 | IP |
218
- | 验证码 | 60 | 3 | IP |
219
- | 查询接口 | 60 | 100-1000 | DEFAULT |
220
- | 写入接口 | 60 | 10-50 | DEFAULT |
221
- | 敏感操作 | 60 | 1-5 | IP |
222
-
223
- ---
224
-
225
- ## 5. 防重复提交(@RepeatSubmit)
226
-
227
- > 位置:`ruoyi-common-idempotent/.../`
96
+ ### 3. 输入校验
228
97
 
229
98
  ```java
230
- import org.dromara.common.idempotent.annotation.RepeatSubmit;
231
-
232
- @RepeatSubmit() // 默认 5 秒
233
- @RepeatSubmit(interval = 10, timeUnit = TimeUnit.SECONDS) // 10 秒
234
- @RepeatSubmit(interval = 5000, message = "请勿重复提交订单") // 自定义消息
235
- ```
99
+ public class UserDTO {
100
+ @NotNull(message = "ID不能为空", groups = {UpdateGroup.class})
101
+ private Long id;
236
102
 
237
- | 场景 | 推荐间隔 |
238
- |------|---------|
239
- | 普通表单 | 3-5 |
240
- | 订单创建 | 10 秒 |
241
- | 支付操作 | 30 秒 |
242
- | 文件上传 | 10 秒 |
103
+ @NotBlank(message = "用户名不能为空")
104
+ @Size(min = 2, max = 20, message = "用户名长度2-20")
105
+ @Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "只能包含字母数字下划线")
106
+ private String username;
243
107
 
244
- ---
108
+ @Email(message = "邮箱格式不正确")
109
+ private String email;
245
110
 
246
- ## 6. 数据权限(@DataPermission)
111
+ @Min(value = 0, message = "年龄不能为负")
112
+ @Max(value = 150, message = "年龄超出范围")
113
+ private Integer age;
114
+ }
247
115
 
248
- > **完整指南请使用 `data-permission` 技能**
116
+ // Controller 分组校验
117
+ @PostMapping
118
+ public Result<?> add(@Validated(AddGroup.class) @RequestBody UserDTO dto) { }
249
119
 
250
- ```java
251
- @DataPermission({
252
- @DataColumn(key = "deptName", value = "create_dept"),
253
- @DataColumn(key = "userName", value = "create_by")
254
- })
255
- public TableDataInfo<OrderVo> pageWithPermission(OrderBo bo, PageQuery pageQuery) { }
120
+ @PutMapping
121
+ public Result<?> update(@Validated(UpdateGroup.class) @RequestBody UserDTO dto) { }
256
122
  ```
257
123
 
258
- 权限类型:全部数据 | 本部门 | 本部门及以下 | 仅本人 | 自定义
259
-
260
- ---
261
-
262
- ## 7. 输入校验
124
+ ### 4. 越权访问防护
263
125
 
264
126
  ```java
265
- import org.dromara.common.core.validate.AddGroup;
266
- import org.dromara.common.core.validate.EditGroup;
267
-
268
- public class UserBo {
269
- @NotNull(message = "ID不能为空", groups = { EditGroup.class })
270
- private Long id;
271
-
272
- @NotBlank(message = "用户名不能为空", groups = { AddGroup.class, EditGroup.class })
273
- @Size(min = 2, max = 20)
274
- @Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "只能包含字母数字下划线")
275
- private String username;
127
+ public [你的VO类] selectById(Long id) {
128
+ var entity = baseMapper.selectById(id);
129
+ if (entity == null) {
130
+ throw new [你的异常类]("数据不存在");
131
+ }
132
+ // 非管理员只能访问自己的数据
133
+ Long currentUserId = [你的安全工具类].getCurrentUserId();
134
+ if (![你的安全工具类].isAdmin() && !entity.getCreatedBy().equals(currentUserId)) {
135
+ throw new [你的异常类]("无权访问此数据");
136
+ }
137
+ return convertToVo(entity);
276
138
  }
277
-
278
- // Controller 分组校验
279
- @PostMapping public R<Long> add(@Validated(AddGroup.class) @RequestBody UserBo bo) { }
280
- @PutMapping public R<Void> update(@Validated(EditGroup.class) @RequestBody UserBo bo) { }
281
139
  ```
282
140
 
283
141
  ---
284
142
 
285
- ## 8. 常见漏洞防护
143
+ ## 常见漏洞防护
286
144
 
287
145
  ### SQL 注入
288
146
 
289
147
  ```java
290
- // NG: "SELECT * FROM user WHERE name = '" + name + "'"
291
- // NG: @Select("SELECT * FROM user WHERE name = '${name}'")
292
- // OK: MyBatis-Plus LambdaQueryWrapper
293
- // OK: @Select("SELECT * FROM user WHERE name = #{name}")
148
+ // 禁止:字符串拼接 SQL
149
+ "SELECT * FROM user WHERE name = '" + name + "'"
150
+ @Select("SELECT * FROM user WHERE name = '${name}'")
151
+
152
+ // 正确:参数化查询
153
+ @Select("SELECT * FROM user WHERE name = #{name}")
154
+ // 或使用 ORM 框架的 QueryWrapper / LambdaQueryWrapper
294
155
  ```
295
156
 
296
- ### 越权访问
157
+ ### XSS 防护
297
158
 
298
159
  ```java
299
- @Override
300
- public OrderVo selectById(Long id) {
301
- Order order = baseMapper.selectById(id);
302
- if (ObjectUtil.isNull(order)) {
303
- throw new ServiceException("订单不存在");
304
- }
305
- if (!LoginHelper.isSuperAdmin() && !order.getUserId().equals(LoginHelper.getUserId())) {
306
- throw new ServiceException("无权访问此订单");
307
- }
308
- return MapstructUtils.convert(order, OrderVo.class);
160
+ // 方式一:全局 Filter(推荐)
161
+ @Bean
162
+ public FilterRegistrationBean<XssFilter> xssFilter() {
163
+ FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();
164
+ registration.setFilter(new XssFilter());
165
+ registration.addUrlPatterns("/*");
166
+ registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
167
+ return registration;
309
168
  }
310
169
 
311
- // 批量操作同样校验归属
170
+ // 方式二:手动转义
171
+ String safe = HtmlUtils.htmlEscape(userInput);
172
+ String safe = StringEscapeUtils.escapeHtml4(userInput);
312
173
  ```
313
174
 
314
175
  ### 敏感信息泄露
315
176
 
316
177
  ```java
317
- // NG: return userDao.getById(id); // 包含密码等
318
- // OK: return MapstructUtils.convert(user, UserVo.class); // VO 过滤敏感字段
319
- // OK: 使用 @Sensitive 自动脱敏
178
+ // 禁止:直接返回 Entity(可能包含密码等)
179
+ return userDao.getById(id);
180
+
181
+ // 正确:使用 VO 过滤 + @Sensitive 脱敏
182
+ UserVo vo = new UserVo();
183
+ BeanUtils.copyProperties(user, vo);
184
+ return vo;
185
+
186
+ // 日志脱敏
187
+ log.info("手机号: {}", DesensitizedUtil.mobilePhone(phone));
320
188
  ```
321
189
 
322
190
  ---
323
191
 
324
- ## 9. 安全检查清单
192
+ ## 安全检查清单
325
193
 
326
194
  ### 代码审查
327
195
 
328
- - [ ] 用户输入经过 `@NotBlank`/`@Size`/`@Pattern` 校验
329
- - [ ] SQL 使用 MyBatis-Plus 或参数化查询(#{}
330
- - [ ] 敏感字段使用 `@Sensitive` 脱敏
331
- - [ ] 需加密字段使用 `@EncryptField`
332
- - [ ] Controller 添加 `@SaCheckPermission`
333
- - [ ] 敏感操作添加 `@RepeatSubmit`
334
- - [ ] 高频接口添加 `@RateLimiter`
196
+ - [ ] 用户输入经过 `@NotBlank` / `@Size` / `@Pattern` 校验
197
+ - [ ] SQL 使用参数化查询(`#{}` 而非 `${}`)
198
+ - [ ] 敏感字段使用脱敏注解或 VO 过滤
199
+ - [ ] 存储敏感数据使用加密
200
+ - [ ] Controller 添加权限注解
201
+ - [ ] 写入接口添加防重复提交
202
+ - [ ] 高频接口添加限流
335
203
  - [ ] 批量操作校验数据归属(防越权)
336
- - [ ] 文件上传校验类型/大小/扩展名
204
+ - [ ] 文件上传校验类型 / 大小 / 扩展名(白名单)
337
205
  - [ ] 日志中无敏感信息(或已脱敏)
338
206
 
339
- ### 配置 & 部署
207
+ ### 配置与部署
340
208
 
341
- - [ ] 生产关闭调试模式
342
- - [ ] 敏感配置已加密或使用环境变量
209
+ - [ ] 生产环境关闭调试模式、Swagger
210
+ - [ ] 敏感配置使用环境变量或配置中心加密
343
211
  - [ ] Token 有效期合理(2-24h)
344
- - [ ] CORS 不使用 `*`
345
- - [ ] 启用 HTTPS、安全响应头
346
- - [ ] 错误页不泄露堆栈、数据库/Redis 端口不对外
212
+ - [ ] CORS 不使用 `*`,限定域名
213
+ - [ ] 启用 HTTPS
214
+ - [ ] 设置安全响应头(X-Frame-Options、X-Content-Type-Options、CSP)
215
+ - [ ] 错误页不泄露堆栈信息
216
+ - [ ] 数据库 / Redis 端口不对外暴露
347
217
 
348
218
  ---
349
219
 
350
- ## 注意事项
220
+ ## 常见错误
221
+
222
+ ```java
223
+ // 1. 忘记加认证注解,接口裸奔
224
+ @GetMapping("/users")
225
+ public Result<?> list() { ... } // 任何人可访问!
351
226
 
352
- - leniu-tengyun-core 项目请使用 `leniu-security-guard` skill
353
- - leniu 使用自研 secure 模块,注解和工具类与 RuoYi-Vue-Plus 不同
227
+ // 2. 只校验前端,不校验后端
228
+ // 前端限制了输入范围,但后端不做校验 -> 可被绕过
229
+
230
+ // 3. 用 Map 传递用户信息(类型不安全)
231
+ Map<String, Object> user = getCurrentUser(); // 缺乏类型约束
232
+ // 应使用强类型 LoginUser 对象
233
+
234
+ // 4. 密码明文存储
235
+ user.setPassword(rawPassword);
236
+ // 应使用 BCrypt / SCrypt 哈希
237
+ user.setPassword(passwordEncoder.encode(rawPassword));
238
+
239
+ // 5. Token 存储敏感信息
240
+ // JWT payload 不应包含密码、完整身份证号等
241
+
242
+ // 6. CORS 配置过于宽松
243
+ .allowedOrigins("*").allowedMethods("*").allowCredentials(true)
244
+ // allowedOrigins("*") 与 allowCredentials(true) 不能同时使用
245
+ ```