Search in sources :

Example 1 with UnsupportedJWTSigningAlgorithmException

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);
    }
}
Also used : ServletException(javax.servlet.ServletException) WebserverAPI(io.supertokens.webserver.WebserverAPI) StorageQueryException(io.supertokens.pluginInterface.exceptions.StorageQueryException) UnsupportedJWTSigningAlgorithmException(io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException) JsonObject(com.google.gson.JsonObject) StorageTransactionLogicException(io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException)

Example 2 with UnsupportedJWTSigningAlgorithmException

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();
}
Also used : RSAPrivateKey(java.security.interfaces.RSAPrivateKey) PrivateKey(java.security.PrivateKey) RSAPublicKey(java.security.interfaces.RSAPublicKey) PublicKey(java.security.PublicKey) RSAPublicKey(java.security.interfaces.RSAPublicKey) UnsupportedJWTSigningAlgorithmException(io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException) RSAPrivateKey(java.security.interfaces.RSAPrivateKey)

Example 3 with 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);
}
Also used : UnsupportedJWTSigningAlgorithmException(io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException) JWTSigningKeyInfo(io.supertokens.pluginInterface.jwt.JWTSigningKeyInfo) Gson(com.google.gson.Gson) JsonObject(com.google.gson.JsonObject) Algorithm(com.auth0.jwt.algorithms.Algorithm)

Example 4 with UnsupportedJWTSigningAlgorithmException

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");
}
Also used : QuitProgramException(io.supertokens.exceptions.QuitProgramException) UnsupportedJWTSigningAlgorithmException(io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException) JWTSigningKeyInfo(io.supertokens.pluginInterface.jwt.JWTSigningKeyInfo) StorageTransactionLogicException(io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException) JWTRecipeSQLStorage(io.supertokens.pluginInterface.jwt.sqlstorage.JWTRecipeSQLStorage) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) JWTRecipeStorage(io.supertokens.pluginInterface.jwt.JWTRecipeStorage) JWTRecipeNoSQLStorage_1(io.supertokens.pluginInterface.jwt.nosqlstorage.JWTRecipeNoSQLStorage_1) List(java.util.List) DuplicateKeyIdException(io.supertokens.pluginInterface.jwt.exceptions.DuplicateKeyIdException)

Example 5 with UnsupportedJWTSigningAlgorithmException

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));
}
Also used : TestingProcessManager(io.supertokens.test.TestingProcessManager) UnsupportedJWTSigningAlgorithmException(io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException) JsonObject(com.google.gson.JsonObject) Test(org.junit.Test)

Aggregations

UnsupportedJWTSigningAlgorithmException (io.supertokens.jwt.exceptions.UnsupportedJWTSigningAlgorithmException)5 JsonObject (com.google.gson.JsonObject)3 StorageTransactionLogicException (io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException)2 JWTSigningKeyInfo (io.supertokens.pluginInterface.jwt.JWTSigningKeyInfo)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2 Algorithm (com.auth0.jwt.algorithms.Algorithm)1 Gson (com.google.gson.Gson)1 QuitProgramException (io.supertokens.exceptions.QuitProgramException)1 StorageQueryException (io.supertokens.pluginInterface.exceptions.StorageQueryException)1 JWTRecipeStorage (io.supertokens.pluginInterface.jwt.JWTRecipeStorage)1 DuplicateKeyIdException (io.supertokens.pluginInterface.jwt.exceptions.DuplicateKeyIdException)1 JWTRecipeNoSQLStorage_1 (io.supertokens.pluginInterface.jwt.nosqlstorage.JWTRecipeNoSQLStorage_1)1 JWTRecipeSQLStorage (io.supertokens.pluginInterface.jwt.sqlstorage.JWTRecipeSQLStorage)1 TestingProcessManager (io.supertokens.test.TestingProcessManager)1 WebserverAPI (io.supertokens.webserver.WebserverAPI)1 PrivateKey (java.security.PrivateKey)1 PublicKey (java.security.PublicKey)1 RSAPrivateKey (java.security.interfaces.RSAPrivateKey)1 RSAPublicKey (java.security.interfaces.RSAPublicKey)1 InvalidKeySpecException (java.security.spec.InvalidKeySpecException)1