Skip to content

Instantly share code, notes, and snippets.

@dmi3coder
Created May 12, 2020 10:54
Show Gist options
  • Save dmi3coder/3f4dec7e1f3aa754d9f69d8ef2fb6f33 to your computer and use it in GitHub Desktop.
Save dmi3coder/3f4dec7e1f3aa754d9f69d8ef2fb6f33 to your computer and use it in GitHub Desktop.
TokenUtils class for Quarkus token security
package tech.donau.quarkify.security;
import org.eclipse.microprofile.jwt.Claims;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.NumericDate;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Map;
/**
* Utilities for generating a JWT for testing
*/
public class TokenUtils {
private TokenUtils() {
}
public static String generateTokenString(JwtClaims claims) throws Exception {
// Use the private key associated with the public key for a valid signature
PrivateKey pk = readPrivateKey("/privateKey.pem");
return generateTokenString(pk, "/privateKey.pem", claims);
}
private static String generateTokenString(PrivateKey privateKey, String kid, JwtClaims claims) throws Exception {
long currentTimeInSecs = currentTimeInSecs();
claims.setIssuedAt(NumericDate.fromSeconds(currentTimeInSecs));
claims.setClaim(Claims.auth_time.name(), NumericDate.fromSeconds(currentTimeInSecs));
for (Map.Entry<String, Object> entry : claims.getClaimsMap().entrySet()) {
System.out.printf("\tAdded claim: %s, value: %s\n", entry.getKey(), entry.getValue());
}
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toJson());
jws.setKey(privateKey);
jws.setKeyIdHeaderValue(kid);
jws.setHeader("typ", "JWT");
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
return jws.getCompactSerialization();
}
/**
* Read a PEM encoded private key from the classpath
*
* @param pemResName - key file resource name
* @return PrivateKey
* @throws Exception on decode failure
*/
public static PrivateKey readPrivateKey(final String pemResName) throws Exception {
InputStream contentIS = TokenUtils.class.getResourceAsStream(pemResName);
byte[] tmp = new byte[4096];
int length = contentIS.read(tmp);
return decodePrivateKey(new String(tmp, 0, length, "UTF-8"));
}
/**
* Decode a PEM encoded private key string to an RSA PrivateKey
*
* @param pemEncoded - PEM string for private key
* @return PrivateKey
* @throws Exception on decode failure
*/
public static PrivateKey decodePrivateKey(final String pemEncoded) throws Exception {
byte[] encodedBytes = toEncodedBytes(pemEncoded);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(keySpec);
}
private static byte[] toEncodedBytes(final String pemEncoded) {
final String normalizedPem = removeBeginEnd(pemEncoded);
return Base64.getDecoder().decode(normalizedPem);
}
private static String removeBeginEnd(String pem) {
pem = pem.replaceAll("-----BEGIN (.*)-----", "");
pem = pem.replaceAll("-----END (.*)----", "");
pem = pem.replaceAll("\r\n", "");
pem = pem.replaceAll("\n", "");
return pem.trim();
}
/**
* @return the current time in seconds since epoch
*/
public static int currentTimeInSecs() {
long currentTimeMS = System.currentTimeMillis();
return (int) (currentTimeMS / 1000);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment