use of io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException in project supertokens-core by supertokens.
the class JWTSigningAPI method doPost.
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
JsonObject input = InputParser.parseJsonObjectOrThrowError(req);
String algorithm = InputParser.parseStringOrThrowError(input, "algorithm", false);
assert algorithm != null;
String jwksDomain = InputParser.parseStringOrThrowError(input, "jwksDomain", false);
assert jwksDomain != null;
JsonObject payload = InputParser.parseJsonObjectOrThrowError(input, "payload", false);
assert payload != null;
long validity = InputParser.parseLongOrThrowError(input, "validity", false);
if (validity <= 0) {
throw new ServletException(new WebserverAPI.BadRequestException("validity must be greater than or equal to 0"));
}
try {
String jwt = JWTSigningFunctions.createJWTToken(main, algorithm.toUpperCase(), payload, jwksDomain, validity);
JsonObject reply = new JsonObject();
reply.addProperty("status", "OK");
reply.addProperty("jwt", jwt);
super.sendJsonResponse(200, reply, resp);
} catch (UnsupportedJWTSigningAlgorithmException e) {
JsonObject reply = new JsonObject();
reply.addProperty("status", UNSUPPORTED_ALGORITHM_ERROR_STATUS);
super.sendJsonResponse(200, reply, resp);
} catch (StorageQueryException | StorageTransactionLogicException | NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new ServletException(e);
}
}
use of io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException in project supertokens-core by supertokens.
the class JWTSigningFunctions method getAuth0Algorithm.
private static Algorithm getAuth0Algorithm(JWTSigningKey.SupportedAlgorithms algorithm, JWTSigningKeyInfo keyToUse) throws NoSuchAlgorithmException, InvalidKeySpecException, UnsupportedJWTSigningAlgorithmException {
// TODO: Abstract this away from the main package to avoid a direct dependency on auth0s package
if (algorithm.equalsString("rs256")) {
PublicKey publicKey = getPublicKeyFromString(((JWTAsymmetricSigningKeyInfo) keyToUse).publicKey, algorithm);
PrivateKey privateKey = getPrivateKeyFromString(((JWTAsymmetricSigningKeyInfo) keyToUse).privateKey, algorithm);
if (publicKey instanceof RSAPublicKey && privateKey instanceof RSAPrivateKey) {
return Algorithm.RSA256((RSAPublicKey) publicKey, (RSAPrivateKey) privateKey);
}
}
throw new UnsupportedJWTSigningAlgorithmException();
}
use of io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException in project supertokens-core by supertokens.
the class JWTSigningFunctions method createJWTToken.
/**
* Creates and returns a JWT string
*
* @param main
* @param algorithm The signing algorithm to use when creating the token. Refer to
* {@link JWTSigningKey.SupportedAlgorithms}
* @param payload JSON object containing user defined claims to be added to the JWT payload
* @param jwksDomain Used as the issuer in the JWT payload
* @param jwtValidity Used to set iat anf exp claims in the JWT payload
* @return String token
* @throws StorageQueryException If there is an error interacting with the database
* @throws StorageTransactionLogicException If there is an error interacting with the database
* @throws NoSuchAlgorithmException If there is an error when using Java's cryptography packages
* @throws InvalidKeySpecException If there is an error when using Java's cryptography packages
* @throws JWTCreationException If there is an error when creating JWTs
* @throws UnsupportedJWTSigningAlgorithmException If the algorithm provided does not match any of the supported
* algorithms
*/
@SuppressWarnings("unchecked")
public static String createJWTToken(Main main, String algorithm, JsonObject payload, String jwksDomain, long jwtValidity) throws StorageQueryException, StorageTransactionLogicException, NoSuchAlgorithmException, InvalidKeySpecException, JWTCreationException, UnsupportedJWTSigningAlgorithmException {
// TODO: In the future we will have a way for the user to send a custom key id to use
JWTSigningKey.SupportedAlgorithms supportedAlgorithm;
try {
supportedAlgorithm = JWTSigningKey.SupportedAlgorithms.valueOf(algorithm);
} catch (IllegalArgumentException e) {
// If it enters this block then the string value provided does not match the algorithms we support
throw new UnsupportedJWTSigningAlgorithmException();
}
JWTSigningKeyInfo keyToUse = JWTSigningKey.getInstance(main).getOrCreateAndGetKeyForAlgorithm(supportedAlgorithm);
// Get an instance of auth0's Algorithm which is needed when signing using auth0's package
Algorithm signingAlgorithm = getAuth0Algorithm(supportedAlgorithm, keyToUse);
// Create the claims for the JWT header
Map<String, Object> headerClaims = new HashMap<>();
// All examples in the RFC have the algorithm
headerClaims.put("alg", supportedAlgorithm.name().toUpperCase());
// in upper case
headerClaims.put("typ", "JWT");
headerClaims.put("kid", keyToUse.keyId);
long currentTimeInMillis = System.currentTimeMillis();
// JWT Expiry is seconds from epoch not millis
long jwtExpiry = Double.valueOf(Math.ceil((currentTimeInMillis / 1000.0))).longValue() + (jwtValidity);
// Add relevant claims to the payload, note we only add/override ones that we absolutely need to.
Map<String, Object> jwtPayload = new Gson().fromJson(payload, HashMap.class);
jwtPayload.putIfAbsent("iss", jwksDomain);
jwtPayload.put("exp", jwtExpiry);
// JWT uses seconds from epoch not millis
jwtPayload.put("iat", currentTimeInMillis / 1000);
return com.auth0.jwt.JWT.create().withPayload(jwtPayload).withHeader(headerClaims).sign(signingAlgorithm);
}
use of io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException in project supertokens-core by supertokens.
the class JWTSigningKey method getOrCreateAndGetKeyForAlgorithm.
/**
* Used to retrieve a key for JWT validation, for a given signing algorithm. If there are no keys in storage that
* match the given algorithm a new one is generated.
*
* @param algorithm The signing algorithm
* @return {@link JWTSigningKeyInfo} key
* @throws UnsupportedJWTSigningAlgorithmException If there is an error in the provided algorithm when
* getting/generating keys
* @throws StorageQueryException If there is an error interacting with the database
* @throws StorageTransactionLogicException If there is an error interacting with the database
*/
public JWTSigningKeyInfo getOrCreateAndGetKeyForAlgorithm(SupportedAlgorithms algorithm) throws UnsupportedJWTSigningAlgorithmException, StorageQueryException, StorageTransactionLogicException {
JWTRecipeStorage storage = StorageLayer.getJWTRecipeStorage(main);
if (storage.getType() == STORAGE_TYPE.SQL) {
JWTRecipeSQLStorage sqlStorage = (JWTRecipeSQLStorage) storage;
try {
return sqlStorage.startTransaction(con -> {
JWTSigningKeyInfo keyInfo = null;
List<JWTSigningKeyInfo> keysFromStorage = sqlStorage.getJWTSigningKeys_Transaction(con);
// will be created after the loop
for (int i = 0; i < keysFromStorage.size(); i++) {
JWTSigningKeyInfo currentKey = keysFromStorage.get(i);
if (algorithm.equalsString(currentKey.algorithm)) {
keyInfo = currentKey;
break;
}
}
// If no key was found create a new one
if (keyInfo == null) {
while (true) {
try {
keyInfo = generateKeyForAlgorithm(algorithm);
sqlStorage.setJWTSigningKey_Transaction(con, keyInfo);
break;
} catch (NoSuchAlgorithmException | UnsupportedJWTSigningAlgorithmException e) {
throw new StorageTransactionLogicException(e);
} catch (DuplicateKeyIdException e) {
// Retry with a new key id
}
}
}
sqlStorage.commitTransaction(con);
return keyInfo;
});
} catch (StorageTransactionLogicException e) {
if (e.actualException instanceof UnsupportedJWTSigningAlgorithmException) {
throw (UnsupportedJWTSigningAlgorithmException) e.actualException;
}
throw e;
}
} else if (storage.getType() == STORAGE_TYPE.NOSQL_1) {
JWTRecipeNoSQLStorage_1 noSQLStorage = (JWTRecipeNoSQLStorage_1) storage;
JWTSigningKeyInfo keyInfo = null;
while (true) {
List<JWTSigningKeyInfo> keysFromStorage = noSQLStorage.getJWTSigningKeys_Transaction();
// will be created after the for loop
for (int i = 0; i < keysFromStorage.size(); i++) {
JWTSigningKeyInfo currentKey = keysFromStorage.get(i);
if (currentKey.algorithm.equalsIgnoreCase(algorithm.name())) {
keyInfo = currentKey;
break;
}
}
// If no key was found create a new one
if (keyInfo == null) {
while (true) {
try {
keyInfo = generateKeyForAlgorithm(algorithm);
boolean success = noSQLStorage.setJWTSigningKeyInfoIfNoKeyForAlgorithmExists_Transaction(keyInfo);
if (!success) {
continue;
}
break;
} catch (NoSuchAlgorithmException e) {
throw new StorageTransactionLogicException(e);
} catch (DuplicateKeyIdException e) {
// Retry with a new key id
}
}
}
return keyInfo;
}
}
throw new QuitProgramException("Unsupported storage type detected");
}
use of io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException in project supertokens-core by supertokens.
the class JWTCreateTest method testInvalidAlgorithmThrowsError.
/**
* Trying to create a JWT with an unsupported algorithm should throw an error
*/
@Test
public void testInvalidAlgorithmThrowsError() throws Exception {
String[] args = { "../" };
TestingProcessManager.TestingProcess process = TestingProcessManager.start(args);
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED));
String algorithm = "HS256";
JsonObject payload = new JsonObject();
payload.addProperty("customClaim", "customValue");
String jwksDomain = "http://localhost";
long validity = 3600;
try {
JWTSigningFunctions.createJWTToken(process.getProcess(), algorithm, payload, jwksDomain, validity);
fail("JWTSigningFunctions.createJWTToken succeeded when it should have failed");
} catch (UnsupportedJWTSigningAlgorithmException e) {
// Do nothing
}
process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}
Aggregations