From a6b2c860762816b1958569de69ba1178cf7273aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=B1=BC=E6=98=9F?= <1772580802@qq.com>
Date: Fri, 12 Jun 2026 10:25:02 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E6=96=B0=E5=A2=9E=E5=8F=AF=E8=A7=86?=
=?UTF-8?q?=E5=8C=96=E9=A1=B5=E9=9D=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 5 +
.../config/SsoServerClientsProperties.java | 52 +++
.../controller/SsoDashboardController.java | 76 ++++
src/main/resources/static/index.html | 325 +++++++++++++++++-
.../SsoDashboardControllerTest.java | 45 +++
5 files changed, 499 insertions(+), 4 deletions(-)
create mode 100644 src/main/java/com/ngskcloud/config/SsoServerClientsProperties.java
create mode 100644 src/main/java/com/ngskcloud/controller/SsoDashboardController.java
create mode 100644 src/test/java/com/ngskcloud/controller/SsoDashboardControllerTest.java
diff --git a/pom.xml b/pom.xml
index 76e2db5..00c78f0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -257,6 +257,11 @@
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0
+
diff --git a/src/main/java/com/ngskcloud/config/SsoServerClientsProperties.java b/src/main/java/com/ngskcloud/config/SsoServerClientsProperties.java
new file mode 100644
index 0000000..d293ff4
--- /dev/null
+++ b/src/main/java/com/ngskcloud/config/SsoServerClientsProperties.java
@@ -0,0 +1,52 @@
+package com.ngskcloud.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+@Component
+@ConfigurationProperties(prefix = "sa-token.sso-server")
+public class SsoServerClientsProperties {
+
+ private Map clients = new LinkedHashMap<>();
+
+ public Map getClients() {
+ return clients;
+ }
+
+ public void setClients(Map clients) {
+ this.clients = clients == null ? new LinkedHashMap<>() : clients;
+ }
+
+ public static class Client {
+ private String client;
+ private String allowUrl;
+ private String secretKey;
+
+ public String getClient() {
+ return client;
+ }
+
+ public void setClient(String client) {
+ this.client = client;
+ }
+
+ public String getAllowUrl() {
+ return allowUrl;
+ }
+
+ public void setAllowUrl(String allowUrl) {
+ this.allowUrl = allowUrl;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public void setSecretKey(String secretKey) {
+ this.secretKey = secretKey;
+ }
+ }
+}
diff --git a/src/main/java/com/ngskcloud/controller/SsoDashboardController.java b/src/main/java/com/ngskcloud/controller/SsoDashboardController.java
new file mode 100644
index 0000000..9e9d714
--- /dev/null
+++ b/src/main/java/com/ngskcloud/controller/SsoDashboardController.java
@@ -0,0 +1,76 @@
+package com.ngskcloud.controller;
+
+import com.ngskcloud.config.SsoServerClientsProperties;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/sso/dashboard")
+public class SsoDashboardController {
+
+ private final SsoServerClientsProperties properties;
+
+ public SsoDashboardController(SsoServerClientsProperties properties) {
+ this.properties = properties;
+ }
+
+ @GetMapping("/clients")
+ public DashboardClientsResponse clients() {
+ List clients = properties.getClients().entrySet().stream()
+ .sorted(Map.Entry.comparingByKey())
+ .map(entry -> toView(entry.getKey(), entry.getValue()))
+ .toList();
+
+ return new DashboardClientsResponse(clients.size(), Instant.now().toString(), clients);
+ }
+
+ private SsoClientView toView(String id, SsoServerClientsProperties.Client client) {
+ String name = valueOrFallback(client.getClient(), id);
+ String allowUrl = valueOrFallback(client.getAllowUrl(), "-");
+ boolean secretConfigured = hasText(client.getSecretKey());
+ String status = hasText(client.getClient()) && secretConfigured ? "CONFIGURED" : "INCOMPLETE";
+
+ return new SsoClientView(
+ id,
+ name,
+ allowUrl,
+ secretConfigured,
+ maskSecret(client.getSecretKey()),
+ status);
+ }
+
+ private String maskSecret(String secretKey) {
+ if (!hasText(secretKey)) {
+ return "";
+ }
+ if (secretKey.length() <= 10) {
+ return "****";
+ }
+ return secretKey.substring(0, 7) + "****" + secretKey.substring(secretKey.length() - 3);
+ }
+
+ private String valueOrFallback(String value, String fallback) {
+ return hasText(value) ? value : fallback;
+ }
+
+ private boolean hasText(String value) {
+ return value != null && !value.trim().isEmpty();
+ }
+
+ public record DashboardClientsResponse(int total, String generatedAt, List clients) {
+ }
+
+ public record SsoClientView(
+ String id,
+ String name,
+ String allowUrl,
+ boolean secretConfigured,
+ String secretPreview,
+ String status) {
+ }
+}
diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html
index 89bb8ba..01219e6 100644
--- a/src/main/resources/static/index.html
+++ b/src/main/resources/static/index.html
@@ -1,6 +1,323 @@
-
+
+
+
+
+
+ SSO 接入平台看板
+
+
-hello word!!!
-this is a html page
+
+
+
+
SSO 接入平台看板
+
查看当前认证中心已配置的平台接入状态
+
+
+
+
+
+
+
+
+ 已配置平台
+ 0
+
+
+ 密钥完整
+ 0
+
+
+ 最后刷新
+ --
+
+
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/src/test/java/com/ngskcloud/controller/SsoDashboardControllerTest.java b/src/test/java/com/ngskcloud/controller/SsoDashboardControllerTest.java
new file mode 100644
index 0000000..c270b99
--- /dev/null
+++ b/src/test/java/com/ngskcloud/controller/SsoDashboardControllerTest.java
@@ -0,0 +1,45 @@
+package com.ngskcloud.controller;
+
+import com.ngskcloud.config.SsoServerClientsProperties;
+import org.junit.jupiter.api.Test;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+class SsoDashboardControllerTest {
+
+ @Test
+ void listsConfiguredClientsWithMaskedSecrets() throws Exception {
+ SsoServerClientsProperties.Client playedu = new SsoServerClientsProperties.Client();
+ playedu.setClient("playedu-client");
+ playedu.setAllowUrl("*");
+ playedu.setSecretKey("SSO-C2-kQwIOrYvnXmSDkwEiFngrKidMcdrgKor");
+
+ SsoServerClientsProperties properties = new SsoServerClientsProperties();
+ properties.setClients(new LinkedHashMap<>(Map.of("sso-client2", playedu)));
+
+ MockMvc mockMvc = MockMvcBuilders
+ .standaloneSetup(new SsoDashboardController(properties))
+ .build();
+
+ mockMvc.perform(get("/sso/dashboard/clients"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.total").value(1))
+ .andExpect(jsonPath("$.clients[0].id").value("sso-client2"))
+ .andExpect(jsonPath("$.clients[0].name").value("playedu-client"))
+ .andExpect(jsonPath("$.clients[0].allowUrl").value("*"))
+ .andExpect(jsonPath("$.clients[0].secretConfigured").value(true))
+ .andExpect(jsonPath("$.clients[0].secretPreview").value("SSO-C2-****Kor"))
+ .andExpect(jsonPath("$.clients[0].status").value("CONFIGURED"))
+ .andExpect(content().string(not(containsString("kQwIOrYvnXmSDkwEiFngrKidMcdrg"))));
+ }
+}