Skip to content
This repository was archived by the owner on Apr 10, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 57 additions & 1 deletion GeneXusJWT/src/main/java/com/genexus/JWT/JWTCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.genexus.JWT.claims.Claim;
import com.genexus.JWT.claims.HeaderParameters;
import com.genexus.JWT.claims.PrivateClaims;
import com.genexus.JWT.claims.PublicClaims;
import com.genexus.JWT.claims.RegisteredClaim;
Expand Down Expand Up @@ -52,6 +53,10 @@ public String doCreate(String algorithm, PrivateClaims privateClaims, JWTOptions
return "";
}
Builder tokenBuilder = JWT.create();
if (!options.getHeaderParameters().isEmpty()) {
HeaderParameters parameters = options.getHeaderParameters();
tokenBuilder.withHeader(parameters.getMap());
}
tokenBuilder = doBuildPayload(tokenBuilder, privateClaims, options);
if (this.hasError()) {
return "";
Expand Down Expand Up @@ -103,7 +108,8 @@ public boolean doVerify(String token, String expectedAlgorithm, PrivateClaims pr
this.error.setError("JW005", e.getMessage());
return false;
}
if (isRevoqued(decodedJWT, options) || !verifyPrivateClaims(decodedJWT, privateClaims, options)) {
if (isRevoqued(decodedJWT, options) || !verifyPrivateClaims(decodedJWT, privateClaims, options)
|| !verifyHeader(decodedJWT, options)) {
return false;
}
String algorithm = decodedJWT.getAlgorithm();
Expand Down Expand Up @@ -386,4 +392,54 @@ private int countingPrivateClaims(Map<String, Object> map, int counter) {
return counter;
}

private boolean verifyHeader(DecodedJWT decodedJWT, JWTOptions options) {
HeaderParameters parameters = options.getHeaderParameters();
if (parameters.isEmpty()) {
return true;
}

List<String> allParms = parameters.getAll();
if (allParms.size() + 2 != getHeaderClaimsNumber(decodedJWT)) {
return false;
}
Map<String, Object> map = parameters.getMap();
for (String s : allParms) {

if (decodedJWT.getHeaderClaim(s) == null) {
return false;
}
com.auth0.jwt.interfaces.Claim c = decodedJWT.getHeaderClaim(s);
String claimValue = null;
try {
claimValue = c.asString().trim();
} catch (NullPointerException e) {
return false;
}
String optionsValue = ((String) map.get(s)).trim();
if (!SecurityUtils.compareStrings(claimValue, optionsValue)) {
return false;
}
}
return true;

}

private int getHeaderClaimsNumber(DecodedJWT decodedJWT) {
String base64Part = decodedJWT.getHeader();
byte[] base64Bytes = Base64.decodeBase64(base64Part);
EncodingUtil eu = new EncodingUtil();
String plainTextPart = eu.getString(base64Bytes);
HashMap<String, Object> map = new HashMap<String, Object>();
ObjectMapper mapper = new ObjectMapper();

try {
map = mapper.readValue(plainTextPart, new TypeReference<Map<String, Object>>() {
});
} catch (Exception e) {
return 0;
}
return map.size();

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.genexus.JWT.claims;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HeaderParameters {
/*
* Cannot avoid typ=JWT because of RFC 7519 https://tools.ietf.org/html/rfc7519
* https://github.com/auth0/java-jwt/issues/369
*/

private Map<String, Object> map;

public HeaderParameters() {
map = new HashMap<String, Object>();
}

public void setParameter(String name, String value) {
map.put(name, value);
}

public Map<String, Object> getMap() {
return this.map;
}

public List<String> getAll() {
return new ArrayList<String>(map.keySet());
}

public boolean isEmpty()
{
if (getAll().size() == 0)
{
return true;
}
return false;
}

}
14 changes: 14 additions & 0 deletions GeneXusJWT/src/main/java/com/genexus/commons/JWTOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.bouncycastle.util.encoders.Hex;

import com.genexus.JWT.claims.HeaderParameters;
import com.genexus.JWT.claims.PublicClaims;
import com.genexus.JWT.claims.RegisteredClaims;
import com.genexus.JWT.utils.RevocationList;
Expand All @@ -18,11 +19,13 @@ public class JWTOptions extends SecurityAPIObject {
private RevocationList revocationList;
private CertificateX509 certificate;
private PrivateKeyManager privateKey;
private HeaderParameters parameters;

public JWTOptions() {
publicClaims = new PublicClaims();
registeredClaims = new RegisteredClaims();
revocationList = new RevocationList();
parameters = new HeaderParameters();
}

/******** EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/
Expand Down Expand Up @@ -70,6 +73,12 @@ public void addRevocationList(RevocationList revocationList) {
public void deteleRevocationList() {
this.revocationList = new RevocationList();
}

public void addHeaderParameter(String name, String value)
{
this.parameters.setParameter(name, value);
}


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

Expand Down Expand Up @@ -113,4 +122,9 @@ public CertificateX509 getCertificate() {
public PrivateKeyManager getPrivateKey() {
return this.privateKey;
}

public HeaderParameters getHeaderParameters()
{
return this.parameters;
}
}