浏览代码

交易市场平台(供应商)

wwh 3 天之前
父节点
当前提交
7741658d30

+ 22 - 0
baqing-admin/src/main/java/com/ruoyi/web/modules/screen/support/ScreenLoginPermissions.java

@@ -0,0 +1,22 @@
1
+package com.ruoyi.web.modules.screen.support;
2
+
3
+import java.util.Collections;
4
+import java.util.Set;
5
+
6
+/**
7
+ * 大屏免密登录成功后注入的菜单权限(覆盖 sys_role 配置,前端可访问全部大屏菜单)。
8
+ */
9
+public final class ScreenLoginPermissions
10
+{
11
+    /** 匹配全部 {@code bigScreen:*:query} 等大屏权限 */
12
+    public static final String BIG_SCREEN_ALL = "bigScreen:*:*";
13
+
14
+    private ScreenLoginPermissions()
15
+    {
16
+    }
17
+
18
+    public static Set<String> all()
19
+    {
20
+        return Collections.singleton(BIG_SCREEN_ALL);
21
+    }
22
+}

+ 1 - 1
baqing-admin/src/main/java/com/ruoyi/web/modules/screen/support/ScreenLoginProperties.java

@@ -17,7 +17,7 @@ public class ScreenLoginProperties
17 17
     /** RSA 私钥(Base64,服务端解密用,勿暴露给前端) */
18 18
     private String rsaPrivateKey = "";
19 19
 
20
-    /** 专用大屏账号(须预置 sys_user,建议仅 bigScreen:* 查询权限) */
20
+    /** 专用大屏账号(须预置 sys_user 且未删除、未停用;权限由服务端注入 bigScreen:*:*) */
21 21
     private String username = "screen_viewer";
22 22
 
23 23
     public boolean isEnabled()

+ 1 - 5
baqing-admin/src/main/java/com/ruoyi/web/modules/screen/support/ScreenLoginService.java

@@ -14,7 +14,6 @@ import com.ruoyi.common.utils.ip.IpUtils;
14 14
 import com.ruoyi.framework.manager.AsyncManager;
15 15
 import com.ruoyi.framework.manager.factory.AsyncFactory;
16 16
 import com.ruoyi.framework.web.service.TokenService;
17
-import com.ruoyi.framework.web.service.UserDetailsServiceImpl;
18 17
 import com.ruoyi.system.service.ISysUserService;
19 18
 import com.ruoyi.web.modules.screen.domain.vo.ScreenLoginRsaPublicKeyVo;
20 19
 
@@ -32,9 +31,6 @@ public class ScreenLoginService
32 31
     @Autowired
33 32
     private ISysUserService userService;
34 33
 
35
-    @Autowired
36
-    private UserDetailsServiceImpl userDetailsService;
37
-
38 34
     @Autowired
39 35
     private TokenService tokenService;
40 36
 
@@ -49,7 +45,7 @@ public class ScreenLoginService
49 45
         assertLoginReady();
50 46
         validateEncryptedToken(encryptedToken);
51 47
         SysUser user = loadScreenUser();
52
-        LoginUser loginUser = (LoginUser) userDetailsService.createLoginUser(user);
48
+        LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, ScreenLoginPermissions.all());
53 49
         userService.updateLoginInfo(user.getUserId(), IpUtils.getIpAddr(), DateUtils.getNowDate());
54 50
         AsyncManager.me().execute(AsyncFactory.recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS,
55 51
                 MessageUtils.message("user.login.success")));

+ 19 - 0
baqing-admin/src/test/java/com/ruoyi/web/modules/screen/support/ScreenLoginPermissionsTest.java

@@ -0,0 +1,19 @@
1
+package com.ruoyi.web.modules.screen.support;
2
+
3
+import static org.junit.jupiter.api.Assertions.assertEquals;
4
+import static org.junit.jupiter.api.Assertions.assertTrue;
5
+
6
+import org.junit.jupiter.api.DisplayName;
7
+import org.junit.jupiter.api.Test;
8
+
9
+@DisplayName("ScreenLoginPermissions")
10
+class ScreenLoginPermissionsTest
11
+{
12
+    @Test
13
+    @DisplayName("包含大屏通配权限")
14
+    void all_containsBigScreenWildcard()
15
+    {
16
+        assertTrue(ScreenLoginPermissions.all().contains(ScreenLoginPermissions.BIG_SCREEN_ALL));
17
+        assertEquals(1, ScreenLoginPermissions.all().size());
18
+    }
19
+}

+ 15 - 7
doc/大屏/免密登录/大屏免密登录技术方案.md

@@ -11,7 +11,8 @@
11 11
 | **后端** | RuoYi **v3.9.2**(springboot2):JDK 8、Spring MVC |
12 12
 | **代码包** | `com.ruoyi.web.modules.screen`(`ScreenLoginController` / `ScreenLoginService` / `ScreenLoginRsaSupport` / `ScreenLoginProperties`) |
13 13
 | **鉴权** | 登录接口 `@Anonymous` 免鉴权;登录成功后与普通若依接口一致,请求头 `Authorization: Bearer <token>` |
14
-| **专用账号** | `sys_user` 预置用户(默认 `screen_viewer`),建议仅授予 `bigScreen:*:query` |
14
+| **专用账号** | `sys_user` 预置用户(默认 `screenviewer`);校验存在且未删除、未停用 |
15
+| **菜单权限** | 登录成功后在 JWT 中注入 `bigScreen:*:*`,前端默认拥有全部大屏菜单与看板接口权限,**无需**在若依中单独授权 |
15 16
 | **加密** | `RSA/ECB/PKCS1Padding`,与若依后台 `jsencrypt` 密钥格式兼容 |
16 17
 | **客户端 IP** | **不校验**白名单/黑名单;仅写入登录日志 |
17 18
 
@@ -42,14 +43,14 @@ bigscreen:
42 43
     enabled: false          # 生产按需 true
43 44
     rsa-public-key: ""      # Base64 公钥(可含换行,服务端会去除空白)
44 45
     rsa-private-key: ""     # Base64 私钥(仅服务端,勿下发前端)
45
-    username: screen_viewer # 专用 sys_user 登录名
46
+    username: screenviewer  # 专用 sys_user 登录名
46 47
 ```
47 48
 
48 49
 | 项 | 说明 |
49 50
 | --- | --- |
50 51
 | `enabled` | `false` 时公钥接口与登录接口均返回「大屏免密登录未启用」 |
51 52
 | `rsa-public-key` / `rsa-private-key` | 须成对;开发环境可与 `ruoyi-ui/src/utils/jsencrypt.js` 中示例密钥一致 |
52
-| `username` | 不存在、已删除或停用时登录失败 |
53
+| `username` | 对应 `sys_user.user_name`;不存在、已删除或停用时登录失败;**无需**在若依中配置大屏菜单权限 |
53 54
 
54 55
 **密钥生成**:可使用 [在线 RSA 密钥对工具](http://web.chacuo.net/netrsakeypair)(JSEncrypt 格式);生产建议 **2048 位**独立密钥对。
55 56
 
@@ -122,7 +123,7 @@ bigscreen:
122 123
 | 未配置密钥 | 大屏免密登录未配置 RSA 密钥 |
123 124
 | 密文为空 / 解密失败 / 明文非 UUID | 大屏登录认证失败 |
124 125
 | 专用账号不存在 | 大屏专用账号不存在 |
125
-| 账号删除 / 停用 | 若依标准 `user.password.delete` / `user.blocked` |
126
+| 账号删除 / 停用 | 若依标准 `user.password.delete` / `user.blocked` |
126 127
 
127 128
 ---
128 129
 
@@ -131,18 +132,25 @@ bigscreen:
131 132
 | 类 | 职责 |
132 133
 | --- | --- |
133 134
 | `ScreenLoginController` | 路由、`X-Screen-Token` / Body 取值 |
134
-| `ScreenLoginService` | 启用与密钥校验、解密验 UUID、加载专用用户、签发 JWT |
135
+| `ScreenLoginService` | 启用与密钥校验、解密验 UUID、校验专用用户状态、注入 `bigScreen:*:*`、签发 JWT |
136
+| `ScreenLoginPermissions` | 大屏免密登录固定权限集 |
135 137
 | `ScreenLoginRsaSupport` | RSA 加解密、`UUID.fromString` 格式校验 |
136 138
 | `ScreenLoginProperties` | 绑定 `bigscreen.login.*` |
137 139
 | `ScreenLoginConfig` | `@EnableConfigurationProperties` |
138 140
 
139 141
 **UUID 校验**:解密明文经 `UUID.fromString` 解析,须为标准 8-4-4-4-12 十六进制格式(大小写均可)。
140 142
 
143
+**权限说明**:
144
+
145
+- 签发 Token 时写入 `permissions = ["bigScreen:*:*"]`,与若依 `SecurityUtils.hasPermi` 通配规则一致。
146
+- `ruoyi-screen` 路由/导航为静态配置,登录成功即可访问全部大屏页面,**不依赖** `getInfo` / `getRouters`。
147
+- 若调用 `GET /getInfo`,若依会按数据库角色刷新权限;大屏场景建议**仅使用免密登录返回的 Token**,勿混用普通登录。
148
+
141 149
 **安全说明**:
142 150
 
143 151
 - 每次登录应生成**新 UUID** 再加密,避免重放固定密文(服务端当前仅校验格式,不存 nonce)。
144 152
 - 私钥仅存服务端配置,禁止写入前端或版本库(生产用环境变量/密钥管理)。
145
-- 大屏看板接口仍依赖 JWT + `bigScreen:*:query` 权限,与免密登录入口分离。
153
+- 大屏看板接口依赖有效 JWT;权限由免密登录注入,**不要求** `screenviewer` 在若依菜单中逐项授权
146 154
 
147 155
 ---
148 156
 
@@ -191,4 +199,4 @@ async function screenAutoLogin(apiBase) {
191 199
 | 畜牧资源 | `/bigScreen/livestockResource` | `bigScreen:livestockResource:query` |
192 200
 | 共同富裕 | `/bigScreen/commonProsperity` | `bigScreen:commonProsperity:query` |
193 201
 
194
-免密登录**不替代**上述权限校验;专用账号须在若依中配置对应菜单权限。
202
+免密登录**不替代** JWT 鉴权;专用账号须在 `sys_user` 中存在且状态正常,**无需**配置大屏菜单权限。

+ 3 - 1
doc/大屏/免密登录/大屏免密登录测试用例.md

@@ -40,7 +40,9 @@
40 40
 | DP-ML-API-005 | 密文为空 | Postman | 已启用 | `POST /bigScreen/login` 无 token | 失败;大屏登录认证失败 |
41 41
 | DP-ML-API-006 | 密文非法 | Postman | 已启用 | `token=not-valid-cipher` | 失败;大屏登录认证失败 |
42 42
 | DP-ML-API-007 | 专用账号不存在 | Postman | `username` 指向不存在用户 | 有效密文登录 | 失败;大屏专用账号不存在 |
43
-| DP-ML-API-008 | 登录后访问看板 | Postman | 登录成功 | `GET /bigScreen/home/dashboard?statYear=2026`,带 `Authorization` | 有权限则 200;无权限 403 |
43
+| DP-ML-API-007a | 账号已删除 | Postman | `del_flag=2` | 有效密文登录 | 失败;`user.password.delete` |
44
+| DP-ML-API-007b | 账号已停用 | Postman | `status=1` | 有效密文登录 | 失败;`user.blocked` |
45
+| DP-ML-API-008 | 登录后访问看板 | Postman | 登录成功 | `GET /bigScreen/home/dashboard?statYear=2026`,带 `Authorization` | 200(JWT 含 `bigScreen:*:*`) |
44 46
 
45 47
 **生成有效密文(联调)**:
46 48