Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4a4564f

Browse files
Thomasludomikula
Thomas
authored andcommitted
add JWT decoder
merge user info from jwt and user endpoint
1 parent8c7ea98 commit4a4564f

File tree

5 files changed

+132
-4
lines changed

5 files changed

+132
-4
lines changed

‎server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/authentication/request/oauth2/request/GenericAuthRequest.java‎

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
importorg.lowcoder.api.authentication.request.AuthException;
44
importorg.lowcoder.api.authentication.request.oauth2.GenericOAuthProviderSource;
55
importorg.lowcoder.api.authentication.request.oauth2.OAuth2RequestContext;
6+
importorg.lowcoder.api.authentication.util.JwtDecoderUtil;
67
importorg.lowcoder.domain.user.model.AuthToken;
78
importorg.lowcoder.domain.user.model.AuthUser;
89
importorg.lowcoder.sdk.auth.Oauth2GenericAuthConfig;
@@ -14,8 +15,7 @@
1415

1516
importjava.util.Map;
1617

17-
importstaticorg.lowcoder.api.authentication.util.AuthenticationUtils.mapToAuthToken;
18-
importstaticorg.lowcoder.api.authentication.util.AuthenticationUtils.mapToAuthUser;
18+
importstaticorg.lowcoder.api.authentication.util.AuthenticationUtils.*;
1919
importstaticorg.lowcoder.sdk.plugin.common.constant.Constants.HTTP_TIMEOUT;
2020

2121
/**
@@ -75,7 +75,22 @@ protected Mono<AuthToken> refreshAuthToken(String refreshToken) {
7575

7676
@Override
7777
protectedMono<AuthUser>getAuthUser(AuthTokenauthToken) {
78-
if(!Boolean.TRUE.equals(config.getUserInfoIntrospection()))returnMono.just(AuthUser.builder().build());
78+
//parse the JWT token
79+
Stringjwt =authToken.getJwt();
80+
Map<String,Object>jwtMap =null;
81+
if(jwt !=null) {
82+
try {
83+
jwtMap =JwtDecoderUtil.decodeJwtPayload(jwt);
84+
}catch (Exceptionignored) {
85+
}
86+
}
87+
88+
if(!Boolean.TRUE.equals(config.getUserInfoIntrospection())) {
89+
if(jwtMap ==null)returnMono.error(newAuthException("No JWT token found"));
90+
returnMono.just(mapToAuthUser(jwtMap,config.getSourceMappings()));
91+
}
92+
93+
Map<String,Object>finalJwtMap =jwtMap;
7994
returnWebClientBuildHelper.builder()
8095
.systemProxy()
8196
.timeoutMs(HTTP_TIMEOUT)
@@ -89,7 +104,8 @@ protected Mono<AuthUser> getAuthUser(AuthToken authToken) {
89104
if (map.containsKey("error") ||map.containsKey("error_description")) {
90105
returnMono.error(newAuthException(JsonUtils.toJson(map)));
91106
}
92-
returnMono.just(mapToAuthUser(map,config.getSourceMappings()));
107+
AuthUsermerged =mergeAuthUser(mapToAuthUser(finalJwtMap,config.getSourceMappings()),mapToAuthUser(map,config.getSourceMappings()));
108+
returnMono.just(merged);
93109
});
94110
}
95111
}

‎server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/authentication/util/AdvancedMapUtils.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class AdvancedMapUtils {
1212
* @return The string value if found, otherwise null.
1313
*/
1414
publicstaticStringgetString(Map<String,Object>map,Stringkey) {
15+
if(key ==null)returnnull;
1516
String[]parts =key.split("\\.");
1617
Objectcurrent =map;
1718

‎server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/authentication/util/AuthenticationUtils.java‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,20 @@ public static AuthUser mapToAuthUser(Map<String, Object> map, HashMap<String, St
9393
.rawUserInfo(map)
9494
.build();
9595
}
96+
97+
/**
98+
* Merge two AuthUser object - overwrite high into low
99+
* @param low base object for merge
100+
* @param high overwriting object
101+
* @return
102+
*/
103+
publicstaticAuthUsermergeAuthUser(AuthUserlow,AuthUserhigh) {
104+
returnAuthUser.builder()
105+
.uid(high.getUid() !=null ?high.getUid() :low.getUid())
106+
.username(high.getUsername() !=null ?high.getUsername() :low.getUsername())
107+
.avatar(high.getAvatar() !=null ?high.getAvatar() :low.getAvatar())
108+
.rawUserInfo(high.getRawUserInfo() !=null ?high.getRawUserInfo() :low.getRawUserInfo())
109+
.authToken(high.getAuthToken() !=null ?high.getAuthToken() :low.getAuthToken())
110+
.build();
111+
}
96112
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
packageorg.lowcoder.api.authentication.util;
2+
3+
importcom.fasterxml.jackson.databind.ObjectMapper;
4+
importjava.util.Base64;
5+
importjava.util.Map;
6+
7+
publicclassJwtDecoderUtil {
8+
9+
privatestaticfinalObjectMapperobjectMapper =newObjectMapper();
10+
11+
/**
12+
* Decodes the payload of a JWT without verifying its signature.
13+
*
14+
* @param jwt The JWT string.
15+
* @return A Map representing the decoded JWT payload.
16+
* @throws Exception if there is an error decoding the JWT.
17+
*/
18+
publicstaticMap<String,Object>decodeJwtPayload(Stringjwt)throwsException {
19+
// Split the JWT into its components
20+
String[]parts =jwt.split("\\.");
21+
if (parts.length <2) {
22+
thrownewIllegalArgumentException("Invalid JWT format.");
23+
}
24+
25+
// Base64-decode the payload
26+
Stringpayload =parts[1];
27+
byte[]decodedBytes =Base64.getUrlDecoder().decode(payload);
28+
29+
// Convert the decoded bytes to a JSON string
30+
StringdecodedString =newString(decodedBytes);
31+
32+
// Convert the JSON string to a Map
33+
returnobjectMapper.readValue(decodedString,Map.class);
34+
}
35+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
packageorg.lowcoder.api.authentication;
2+
3+
importorg.junit.jupiter.api.Test;
4+
importorg.lowcoder.api.authentication.util.JwtDecoderUtil;
5+
6+
importjava.util.Map;
7+
8+
importstaticorg.junit.jupiter.api.Assertions.*;
9+
10+
classJwtDecoderUtilTest {
11+
12+
@Test
13+
voidtestDecodeJwtPayload_ValidJwt()throwsException {
14+
// Example JWT with payload: {"sub":"1234567890","name":"John Doe","iat":1516239022}
15+
Stringjwt ="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
16+
17+
Map<String,Object>payload =JwtDecoderUtil.decodeJwtPayload(jwt);
18+
19+
assertNotNull(payload);
20+
assertEquals("1234567890",payload.get("sub"));
21+
assertEquals("John Doe",payload.get("name"));
22+
assertEquals(1516239022,payload.get("iat"));
23+
}
24+
25+
@Test
26+
voidtestDecodeJwtPayload_InvalidJwtFormat() {
27+
// Example of an invalid JWT (missing parts)
28+
Stringjwt ="invalid-jwt";
29+
30+
Exceptionexception =assertThrows(IllegalArgumentException.class, () -> {
31+
JwtDecoderUtil.decodeJwtPayload(jwt);
32+
});
33+
34+
assertEquals("Invalid JWT format.",exception.getMessage());
35+
}
36+
37+
@Test
38+
voidtestDecodeJwtPayload_InvalidBase64() {
39+
// Example of a JWT with an invalid base64 payload part
40+
Stringjwt ="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.invalid-base64.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
41+
42+
Exceptionexception =assertThrows(Exception.class, () -> {
43+
JwtDecoderUtil.decodeJwtPayload(jwt);
44+
});
45+
46+
assertTrue(exceptioninstanceofIllegalArgumentException ||exceptioninstanceofjava.io.IOException);
47+
}
48+
49+
@Test
50+
voidtestDecodeJwtPayload_EmptyPayload()throwsException {
51+
// Example of a JWT with an empty payload
52+
Stringjwt ="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
53+
54+
Exceptionexception =assertThrows(Exception.class, () -> {
55+
JwtDecoderUtil.decodeJwtPayload(jwt);
56+
});
57+
58+
assertTrue(exceptioninstanceofjava.io.IOException);
59+
}
60+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp