Skip to content

Commit 8b210d9

Browse files
committed
feat: use session url
1 parent 5ea214d commit 8b210d9

8 files changed

Lines changed: 284 additions & 39 deletions

File tree

backend/api-gateway/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@
109109
<artifactId>mockito-junit-jupiter</artifactId>
110110
<scope>test</scope>
111111
</dependency>
112+
<dependency>
113+
<groupId>org.apache.tomcat.embed</groupId>
114+
<artifactId>tomcat-embed-core</artifactId>
115+
</dependency>
112116
</dependencies>
113117

114118
<build>

backend/api-gateway/src/main/java/com/datamate/gateway/common/filter/AuthFilter.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.springframework.beans.factory.annotation.Value;
1212
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
1313
import org.springframework.cloud.gateway.filter.GlobalFilter;
14+
import org.springframework.core.Ordered;
1415
import org.springframework.core.io.buffer.DataBuffer;
1516
import org.springframework.http.HttpStatus;
1617
import org.springframework.http.MediaType;
@@ -29,7 +30,7 @@
2930
@Slf4j
3031
@Component
3132
@RequiredArgsConstructor
32-
public class AuthFilter implements GlobalFilter {
33+
public class AuthFilter implements GlobalFilter, Ordered {
3334
private static final String AUTH_HEADER = "Authorization";
3435

3536
private static final String TOKEN_PREFIX = "Bearer ";
@@ -95,4 +96,14 @@ private Mono<Void> sendUnauthorizedResponse(ServerWebExchange exchange) {
9596
DataBuffer buffer = response.bufferFactory().wrap(bytes);
9697
return response.writeWith(Mono.just(buffer));
9798
}
99+
100+
/**
101+
* JWT 认证优先级低于 SSO
102+
*
103+
* @return order value (2 = lower priority than SSO filter)
104+
*/
105+
@Override
106+
public int getOrder() {
107+
return 2;
108+
}
98109
}

backend/api-gateway/src/main/java/com/datamate/gateway/common/filter/OmsAuthFilter.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.springframework.beans.factory.annotation.Value;
55
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
66
import org.springframework.cloud.gateway.filter.GlobalFilter;
7+
import org.springframework.core.Ordered;
78
import org.springframework.http.HttpCookie;
89
import org.springframework.http.HttpStatus;
910
import org.springframework.http.server.reactive.ServerHttpRequest;
@@ -20,13 +21,13 @@
2021

2122
/**
2223
* OmsAuthFilter is a global filter that authenticates requests to the OMS service.
23-
*
24+
*
2425
* @author songyongtan
2526
* @date 2026-03-16
2627
*/
2728
@Slf4j
2829
@Component
29-
public class OmsAuthFilter implements GlobalFilter {
30+
public class OmsAuthFilter implements GlobalFilter, Ordered {
3031
private static final String USER_NAME_HEADER = "X-User-Name";
3132
private static final String USER_GROUP_ID_HEADER = "X-User-Group-Id";
3233
private static final String AUTH_TOKEN_KEY = "__Host-X-Auth-Token";
@@ -122,7 +123,7 @@ private String getRealIp(ServerHttpRequest request) {
122123

123124
/**
124125
* getToken gets the token value from cookies.
125-
*
126+
*
126127
* @param cookies the cookies map
127128
* @param tokenKey the token key
128129
* @return the token value
@@ -133,4 +134,14 @@ private String getToken(MultiValueMap<String, HttpCookie> cookies, String tokenK
133134
}
134135
return "";
135136
}
137+
138+
/**
139+
* SSO 认证优先级最高
140+
*
141+
* @return order value (1 = highest priority for auth filters)
142+
*/
143+
@Override
144+
public int getOrder() {
145+
return 1;
146+
}
136147
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.datamate.gateway.interfaces.dto;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
/**
9+
* 用户信息响应
10+
*
11+
* 支持双认证模式:
12+
* - SSO: 通过 OMS 单点登录
13+
* - JWT: 通过本地 JWT Token 认证
14+
* - NONE: 未登录
15+
*/
16+
@Data
17+
@Builder
18+
@NoArgsConstructor
19+
@AllArgsConstructor
20+
public class UserResponse {
21+
/**
22+
* 用户名
23+
*/
24+
private String username;
25+
26+
/**
27+
* 邮箱(JWT 模式可用)
28+
*/
29+
private String email;
30+
31+
/**
32+
* 用户组 ID(SSO 模式可用)
33+
*/
34+
private String groupId;
35+
36+
/**
37+
* 是否已认证
38+
*/
39+
private Boolean authenticated;
40+
41+
/**
42+
* 认证模式
43+
*/
44+
private String authMode; // "SSO" | "JWT" | "NONE"
45+
}

backend/api-gateway/src/main/java/com/datamate/gateway/interfaces/rest/UserController.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@
44
import com.datamate.common.infrastructure.common.Response;
55
import com.datamate.common.infrastructure.exception.CommonErrorCode;
66
import com.datamate.gateway.application.UserApplicationService;
7+
import com.datamate.gateway.domain.service.UserService;
78
import com.datamate.gateway.interfaces.dto.LoginRequest;
89
import com.datamate.gateway.interfaces.dto.LoginResponse;
910
import com.datamate.gateway.interfaces.dto.RegisterRequest;
11+
import com.datamate.gateway.interfaces.dto.UserResponse;
12+
import jakarta.servlet.http.HttpServletRequest;
1013
import jakarta.validation.Valid;
1114
import lombok.RequiredArgsConstructor;
1215
import lombok.extern.slf4j.Slf4j;
16+
import org.apache.commons.lang3.StringUtils;
1317
import org.springframework.http.HttpStatus;
1418
import org.springframework.http.ResponseEntity;
1519
import org.springframework.validation.annotation.Validated;
20+
import org.springframework.web.bind.annotation.GetMapping;
1621
import org.springframework.web.bind.annotation.PostMapping;
1722
import org.springframework.web.bind.annotation.RequestBody;
1823
import org.springframework.web.bind.annotation.RequestMapping;
@@ -30,6 +35,7 @@
3035
@RequiredArgsConstructor
3136
public class UserController {
3237
private final UserApplicationService userApplicationService;
38+
private final UserService userService;
3339

3440
@PostMapping("/login")
3541
@IgnoreResponseWrap
@@ -48,4 +54,54 @@ public ResponseEntity<Response<LoginResponse>> register(@Valid @RequestBody Regi
4854
.orElseGet(() -> ResponseEntity.status(HttpStatus.BAD_REQUEST)
4955
.body(Response.error(CommonErrorCode.SIGNUP_ERROR)));
5056
}
57+
58+
/**
59+
* 获取当前登录用户信息(支持双模式)
60+
* 优先级:
61+
* 1. SSO 模式:检查 OMS 请求头 (X-User-Name, X-User-Group-Id)
62+
* 2. JWT 模式:检查 Authorization Bearer Token
63+
* 3. 未登录:返回 authenticated=false
64+
*
65+
* @param request HTTP 请求
66+
* @return 用户信息(包含认证模式)
67+
*/
68+
@GetMapping("/me")
69+
public Response<UserResponse> getCurrentUser(HttpServletRequest request) {
70+
// 优先检查 SSO 模式(OMS 请求头)
71+
String ssoUsername = request.getHeader("X-User-Name");
72+
String ssoGroupId = request.getHeader("X-User-Group-Id");
73+
74+
if (StringUtils.isNotBlank(ssoUsername)) {
75+
log.info("SSO mode: user={}, groupId={}", ssoUsername, ssoGroupId);
76+
return Response.ok(UserResponse.builder()
77+
.username(ssoUsername)
78+
.groupId(ssoGroupId)
79+
.authenticated(true)
80+
.authMode("SSO")
81+
.build());
82+
}
83+
84+
// 检查独立登录模式(JWT Token)
85+
String authHeader = request.getHeader("Authorization");
86+
if (authHeader != null && authHeader.startsWith("Bearer ")) {
87+
String token = authHeader.substring(7);
88+
String username = userService.validateToken(token);
89+
90+
if (StringUtils.isNotBlank(username)) {
91+
log.info("JWT mode: user={}", username);
92+
return Response.ok(UserResponse.builder()
93+
.username(username)
94+
.authenticated(true)
95+
.authMode("JWT")
96+
.build());
97+
}
98+
}
99+
100+
// 未登录
101+
log.debug("User not authenticated");
102+
return Response.ok(UserResponse.builder()
103+
.authenticated(false)
104+
.authMode("NONE")
105+
.build());
106+
}
51107
}

frontend/src/i18n/locales/en/common.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,22 @@
77
"actions": {
88
"login": "Login",
99
"register": "Register",
10-
"logout": "Logout"
10+
"logout": "Logout",
11+
"gotoLogin": "Go to Login"
1112
},
13+
"authMode": {
14+
"sso": "SSO Login",
15+
"jwt": "JWT Login"
16+
},
17+
"group": "Group",
1218
"messages": {
1319
"loginSuccess": "Login successful",
1420
"loginFailed": "Login failed, please try again later",
1521
"signupSuccess": "Registration successful, auto-login",
1622
"signupFailed": "Registration failed, please try again later",
1723
"logoutSuccess": "Logged out successfully",
18-
"passwordMismatch": "Passwords do not match"
24+
"passwordMismatch": "Passwords do not match",
25+
"useSSO": "Please use ModelEngine single sign-on to register"
1926
},
2027
"loginDialog": {
2128
"title": "Login",

frontend/src/i18n/locales/zh/common.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,22 @@
77
"actions": {
88
"login": "登录",
99
"register": "注册",
10-
"logout": "退出登录"
10+
"logout": "退出登录",
11+
"gotoLogin": "前往登录"
1112
},
13+
"authMode": {
14+
"sso": "单点登录",
15+
"jwt": "令牌登录"
16+
},
17+
"group": "用户组",
1218
"messages": {
1319
"loginSuccess": "登录成功",
1420
"loginFailed": "登录失败,请稍后重试",
1521
"signupSuccess": "注册成功,已自动登录",
1622
"signupFailed": "注册失败,请稍后重试",
1723
"logoutSuccess": "已退出登录",
18-
"passwordMismatch": "两次输入的密码不一致"
24+
"passwordMismatch": "两次输入的密码不一致",
25+
"useSSO": "请使用 ModelEngine 单点登录进行注册"
1926
},
2027
"loginDialog": {
2128
"title": "登录",

0 commit comments

Comments
 (0)