Skip to content
This repository was archived by the owner on Apr 10, 2025. It is now read-only.

Commit d1fcb6c

Browse files
authored
Issue#97338 (#85)
* Refactor JWTModule * Fix error codes and descriptions * Fix version for v18
1 parent a411d16 commit d1fcb6c

File tree

8 files changed

+130
-115
lines changed

8 files changed

+130
-115
lines changed

GeneXusJWT/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<dependency>
2727
<groupId>com.auth0</groupId>
2828
<artifactId>java-jwt</artifactId>
29-
<version>3.10.3</version>
29+
<version>4.0.0</version>
3030
</dependency>
3131
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
3232
<dependency>

GeneXusJWT/src/main/java/com/genexus/JWT/JWTCreator.java

Lines changed: 93 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -43,119 +43,134 @@ public JWTCreator() {
4343
}
4444

4545
/******** EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/
46+
4647
public String doCreate(String algorithm, PrivateClaims privateClaims, JWTOptions options) {
4748
this.error.cleanError();
48-
if (options.hasError()) {
49-
this.error = options.getError();
50-
return "";
51-
}
52-
JWTAlgorithm alg = JWTAlgorithm.getJWTAlgorithm(algorithm, this.error);
53-
if (this.hasError()) {
54-
return "";
55-
}
56-
Builder tokenBuilder = JWT.create();
57-
if (!options.getHeaderParameters().isEmpty()) {
58-
HeaderParameters parameters = options.getHeaderParameters();
59-
tokenBuilder.withHeader(parameters.getMap());
60-
}
61-
tokenBuilder = doBuildPayload(tokenBuilder, privateClaims, options);
62-
if (this.hasError()) {
63-
return "";
64-
}
65-
Algorithm algorithmType = null;
66-
if (JWTAlgorithm.isPrivate(alg)) {
67-
68-
PrivateKeyManager key = options.getPrivateKey();
69-
if (key.hasError()) {
70-
this.error = key.getError();
71-
return "";
72-
}
73-
74-
algorithmType = JWTAlgorithm.getAsymmetricAlgorithm(alg, key, null, error);
75-
if (this.hasError()) {
76-
return "";
77-
}
78-
79-
} else {
80-
81-
algorithmType = JWTAlgorithm.getSymmetricAlgorithm(alg, options.getSecret(), this.error);
82-
if (this.hasError()) {
83-
return "";
84-
}
85-
}
86-
String signedJwt = "";
87-
try {
88-
signedJwt = tokenBuilder.sign(algorithmType);
89-
} catch (Exception e) {
90-
this.error.setError("JW003", e.getMessage());
91-
return "";
92-
}
93-
94-
return signedJwt;
49+
return create_Aux(algorithm, privateClaims, options);
9550
}
9651

9752
public boolean doVerify(String token, String expectedAlgorithm, PrivateClaims privateClaims, JWTOptions options) {
53+
this.error.cleanError();
9854
return doVerify(token, expectedAlgorithm, privateClaims, options, true, true);
9955
}
10056

10157
public boolean doVerifyJustSignature(String token, String expectedAlgorithm, JWTOptions options) {
58+
this.error.cleanError();
10259
return doVerify(token, expectedAlgorithm, null, options, false, false);
10360
}
10461

10562
public boolean doVerifySignature(String token, String expectedAlgorithm, JWTOptions options) {
63+
this.error.cleanError();
10664
return doVerify(token, expectedAlgorithm, null, options, false, true);
10765
}
10866

10967
public String getPayload(String token) {
68+
this.error.cleanError();
11069
String res = "";
11170
try {
11271
res = getTokenPart(token, "payload");
11372
} catch (Exception e) {
114-
this.error.setError("JW009", e.getMessage());
73+
this.error.setError("JW001", e.getMessage());
11574
return "";
11675
}
11776
return res;
11877

11978
}
12079

12180
public String getHeader(String token) {
81+
this.error.cleanError();
12282
String res = "";
12383
try {
12484
res = getTokenPart(token, "header");
12585
} catch (Exception e) {
126-
this.error.setError("JW010", e.getMessage());
86+
this.error.setError("JW002", e.getMessage());
12787
return "";
12888
}
12989
return res;
13090
}
13191

13292
public String getTokenID(String token) {
93+
this.error.cleanError();
13394
String res = "";
13495
try {
13596

13697
res = getTokenPart(token, "id");
13798
} catch (Exception e) {
138-
this.error.setError("JW011", e.getMessage());
99+
this.error.setError("JW003", e.getMessage());
139100
return "";
140101
}
141102
return res;
142103
}
143104

144105
/******** EXTERNAL OBJECT PUBLIC METHODS - END ********/
145106

107+
private String create_Aux(String algorithm, PrivateClaims privateClaims, JWTOptions options) {
108+
if (options == null) {
109+
this.error.setError("JW004", "Options parameter is null");
110+
return "";
111+
}
112+
JWTAlgorithm alg = JWTAlgorithm.getJWTAlgorithm(algorithm, this.error);
113+
if (this.hasError()) {
114+
return "";
115+
}
116+
Builder tokenBuilder = JWT.create();
117+
if (!options.getHeaderParameters().isEmpty()) {
118+
HeaderParameters parameters = options.getHeaderParameters();
119+
tokenBuilder.withHeader(parameters.getMap());
120+
}
121+
if (privateClaims == null) {
122+
this.error.setError("JW005", "PrivateClaims parameter is null");
123+
return "";
124+
}
125+
tokenBuilder = doBuildPayload(tokenBuilder, privateClaims, options);
126+
if (this.hasError()) {
127+
return "";
128+
}
129+
Algorithm algorithmType = null;
130+
if (JWTAlgorithm.isPrivate(alg)) {
131+
132+
PrivateKeyManager key = options.getPrivateKey();
133+
if (key.hasError()) {
134+
this.error = key.getError();
135+
return "";
136+
}
137+
138+
algorithmType = JWTAlgorithm.getAsymmetricAlgorithm(alg, key, null, error);
139+
if (this.hasError()) {
140+
return "";
141+
}
142+
143+
} else {
144+
145+
algorithmType = JWTAlgorithm.getSymmetricAlgorithm(alg, options.getSecret(), this.error);
146+
if (this.hasError()) {
147+
return "";
148+
}
149+
}
150+
String signedJwt = "";
151+
try {
152+
signedJwt = tokenBuilder.sign(algorithmType);
153+
} catch (Exception e) {
154+
this.error.setError("JW006", e.getMessage());
155+
return "";
156+
}
157+
158+
return signedJwt;
159+
}
160+
146161
private boolean doVerify(String token, String expectedAlgorithm, PrivateClaims privateClaims, JWTOptions options,
147162
boolean verifyClaims, boolean verifyRegClaims) {
148-
this.error.cleanError();
149-
if (options.hasError()) {
150-
this.error = options.getError();
163+
164+
if (options == null) {
165+
this.error.setError("JW004", "Options parameter is null");
151166
return false;
152167
}
153168
DecodedJWT decodedJWT = null;
154169
try {
155170
decodedJWT = JWT.decode(token);
156171

157172
} catch (Exception e) {
158-
this.error.setError("JW005", e.getMessage());
173+
this.error.setError("JW007", e.getMessage());
159174
return false;
160175
}
161176
if (isRevoqued(decodedJWT, options)) {
@@ -199,14 +214,14 @@ private boolean doVerify(String token, String expectedAlgorithm, PrivateClaims p
199214
if (this.hasError()) {
200215
return false;
201216
}
202-
203217
try {
204218
JWTVerifier verifier = verification.build();
205219
DecodedJWT decodedToken = JWT.decode(token);
206220

207221
verifier.verify(decodedToken);
208222
} catch (Exception e) {
209-
error.setError("JW006", e.getMessage());
223+
224+
error.setError("JW009", e.getMessage());
210225
return false;
211226
}
212227

@@ -227,7 +242,7 @@ private String getTokenPart(String token, String part) throws Exception {
227242
case "id":
228243
return decodedToken.getId();
229244
default:
230-
error.setError("JW007", "Unknown token segment");
245+
error.setError("JW010", "Unknown token segment");
231246
return "";
232247
}
233248
byte[] base64Bytes = Base64.decodeBase64(base64Part);
@@ -268,7 +283,7 @@ private Verification buildVerification(Verification verification, JWTOptions opt
268283
return null;
269284
}
270285
} else {
271-
error.setError("JW002", registeredC.get(z).getKey() + " wrong registered claim key");
286+
error.setError("JW011", String.format("%s wrong registered claim key", registeredC.get(z).getKey()));
272287
return null;
273288
}
274289
}
@@ -298,12 +313,12 @@ private Builder doBuildPayload(Builder tokenBuilder, PrivateClaims privateClaims
298313
} else if (obj instanceof Boolean) {
299314
tokenBuilder.withClaim(privateC.get(i).getKey(), (boolean) privateC.get(i).getValue());
300315
} else {
301-
this.error.setError("JW012", "Unrecognized data type");
316+
this.error.setError("JW016", "Unrecognized data type");
302317
}
303318
// tokenBuilder.withClaim(privateC.get(i).getKey(), privateC.get(i).getValue());
304319
}
305320
} catch (Exception e) {
306-
this.error.setError("JW004", e.getMessage());
321+
this.error.setError("JW012", e.getMessage());
307322
return null;
308323
}
309324
}
@@ -315,7 +330,7 @@ private Builder doBuildPayload(Builder tokenBuilder, PrivateClaims privateClaims
315330
try {
316331
tokenBuilder.withClaim(publicC.get(j).getKey(), (String) publicC.get(j).getValue());
317332
} catch (Exception e) {
318-
this.error.setError("JW003", e.getMessage());
333+
this.error.setError("JW013", e.getMessage());
319334
return null;
320335
}
321336
}
@@ -332,7 +347,7 @@ private Builder doBuildPayload(Builder tokenBuilder, PrivateClaims privateClaims
332347
return null;
333348
}
334349
} else {
335-
error.setError("JW002", registeredC.get(z).getKey() + " wrong registered claim key");
350+
error.setError("JW011", String.format("%s wrong registered claim key", registeredC.get(z).getKey()));
336351
return null;
337352
}
338353
}
@@ -358,7 +373,7 @@ private boolean verifyPrivateClaims(DecodedJWT decodedJWT, PrivateClaims private
358373
map = (HashMap<String, Object>) mapper.readValue(plainTextPart, new TypeReference<Map<String, Object>>() {
359374
});
360375
} catch (Exception e) {
361-
this.error.setError("JW009", "Cannot parse JWT payload");
376+
this.error.setError("JW014", e.getMessage());
362377
return false;
363378
}
364379
this.counter = 0;
@@ -394,23 +409,21 @@ private boolean verifyNestedClaims(Map<String, Object> pclaimMap, Map<String, Ob
394409
if (!SecurityUtils.compareStrings(((String) op).trim(), ((String) ot).trim())) {
395410
return false;
396411
}
397-
398-
} else if((op instanceof Integer || op instanceof Long) && (ot instanceof Integer || ot instanceof Long)) {
399-
if((convertToLong(op)).compareTo(convertToLong(ot)) != 0)
400-
{
412+
413+
} else if ((op instanceof Integer || op instanceof Long)
414+
&& (ot instanceof Integer || ot instanceof Long)) {
415+
if ((convertToLong(op)).compareTo(convertToLong(ot)) != 0) {
401416
return false;
402417
}
403-
}else if((op instanceof Double && ot instanceof Double)) {
404-
if((double)op != (double)ot)
405-
{
418+
} else if ((op instanceof Double && ot instanceof Double)) {
419+
if ((double) op != (double) ot) {
406420
return false;
407421
}
408-
}else if((op instanceof Boolean && ot instanceof Boolean)) {
409-
if(Boolean.compare((boolean)op, (boolean)ot) != 0)
410-
{
422+
} else if ((op instanceof Boolean && ot instanceof Boolean)) {
423+
if (Boolean.compare((boolean) op, (boolean) ot) != 0) {
411424
return false;
412425
}
413-
}else if (op instanceof HashMap && ot instanceof HashMap) {
426+
} else if (op instanceof HashMap && ot instanceof HashMap) {
414427
@SuppressWarnings("unchecked")
415428
boolean flag = verifyNestedClaims((HashMap<String, Object>) op, (HashMap<String, Object>) ot,
416429
registeredClaims, publicClaims);
@@ -511,12 +524,12 @@ private int getHeaderClaimsNumber(DecodedJWT decodedJWT) {
511524
return map.size();
512525

513526
}
514-
515-
private Long convertToLong(Object o){
516-
String stringToConvert = String.valueOf(o);
517-
Long convertedLong = Long.parseLong(stringToConvert);
518-
return convertedLong;
519527

520-
}
528+
private Long convertToLong(Object o) {
529+
String stringToConvert = String.valueOf(o);
530+
Long convertedLong = Long.parseLong(stringToConvert);
531+
return convertedLong;
532+
533+
}
521534

522535
}

GeneXusJWT/src/main/java/com/genexus/JWT/claims/Claims.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public Object getClaimValue(String key, Error error) {
3030
return claims.get(i).getValue();
3131
}
3232
}
33-
error.setError("CL001", "Could not find a claim with" + key + " key value");
33+
error.setError("CLA01", String.format("Could not find a claim with %s key value", key));
3434
return "";
3535
}
3636

0 commit comments

Comments
 (0)