Search in sources :

Example 11 with Errors

use of io.helidon.common.Errors in project helidon by oracle.

the class JwtProvider method authenticateToken.

private AuthenticationResponse authenticateToken(String token) {
    SignedJwt signedJwt;
    try {
        signedJwt = SignedJwt.parseToken(token);
    } catch (Exception e) {
        // invalid token
        return failOrAbstain("Invalid token" + e);
    }
    if (verifySignature) {
        Errors errors = signedJwt.verifySignature(verifyKeys, defaultJwk);
        if (errors.isValid()) {
            Jwt jwt = signedJwt.getJwt();
            // verify the audience is correct
            Errors validate = jwt.validate(null, expectedAudience);
            if (validate.isValid()) {
                return AuthenticationResponse.success(buildSubject(jwt, signedJwt));
            } else {
                return failOrAbstain("Audience is invalid or missing: " + expectedAudience);
            }
        } else {
            return failOrAbstain(errors.toString());
        }
    } else {
        return AuthenticationResponse.success(buildSubject(signedJwt.getJwt(), signedJwt));
    }
}
Also used : Errors(io.helidon.common.Errors) SignedJwt(io.helidon.security.jwt.SignedJwt) Jwt(io.helidon.security.jwt.Jwt) SignedJwt(io.helidon.security.jwt.SignedJwt) JwtException(io.helidon.security.jwt.JwtException)

Example 12 with Errors

use of io.helidon.common.Errors in project helidon by oracle.

the class EncryptedJwt method decrypt.

/**
 * Decrypt {@link SignedJwt} from the content of the encrypted jwt.
 * If the kid header is specified among encrypted JWT headers, it will be used to match corresponding key
 * from the jwkKeys. If no kid is specified, provided default Jwk is used.
 *
 * Used {@link Jwk} needs to have private key set.
 *
 * @param jwkKeys    jwk keys
 * @param defaultJwk default jwk
 * @return empty optional if any error has occurred or SignedJwt instance if the decryption and validation was successful
 */
public SignedJwt decrypt(JwkKeys jwkKeys, Jwk defaultJwk) {
    Errors.Collector errors = Errors.collector();
    String headerBase64 = encode(header.headerJson().toString().getBytes(StandardCharsets.UTF_8));
    String alg = header.algorithm().orElse(null);
    String kid = header.keyId().orElse(null);
    String enc = header.encryption().orElse(null);
    Jwk jwk = null;
    String algorithm = null;
    if (kid != null) {
        if (jwkKeys != null) {
            jwk = jwkKeys.forKeyId(kid).orElse(null);
        } else if (kid.equals(defaultJwk.keyId())) {
            jwk = defaultJwk;
        } else {
            errors.fatal("Could not find JWK for kid: " + kid);
        }
    } else {
        jwk = defaultJwk;
        if (jwk == null) {
            errors.fatal("Could not find any suitable JWK.");
        }
    }
    if (enc == null) {
        errors.fatal("Content encryption algorithm not set.");
    }
    if (alg != null) {
        try {
            SupportedAlgorithm supportedAlgorithm = SupportedAlgorithm.getValue(alg);
            algorithm = RSA_ALGORITHMS.get(supportedAlgorithm);
        } catch (IllegalArgumentException e) {
            errors.fatal("Value of the claim alg not supported. alg: " + alg);
        }
    } else {
        errors.fatal("No alg header was present among JWE headers");
    }
    PrivateKey privateKey = null;
    Jwk finalJwk = jwk;
    if (jwk instanceof JwkRSA) {
        privateKey = ((JwkRSA) jwk).privateKey().orElseGet(() -> {
            errors.fatal("No private key present in RSA JWK kid: " + finalJwk.keyId());
            return null;
        });
    } else if (jwk instanceof JwkEC) {
        privateKey = ((JwkEC) jwk).privateKey().orElseGet(() -> {
            errors.fatal("No private key present in EC JWK kid: " + finalJwk.keyId());
            return null;
        });
    } else if (jwk != null) {
        errors.fatal("Not supported JWK type: " + jwk.keyType() + ", JWK class: " + jwk.getClass().getName());
    } else {
        errors.fatal("No JWK found for key id: " + kid);
    }
    errors.collect().checkValid();
    byte[] decryptedKey = decryptRsa(algorithm, privateKey, encryptedKey);
    // Base64 headers are used as an aad. This aad has to be in US_ASCII encoding.
    EncryptionParts encryptionParts = new EncryptionParts(decryptedKey, iv, headerBase64.getBytes(StandardCharsets.US_ASCII), encryptedPayload, authTag);
    AesAlgorithm aesAlgorithm;
    try {
        SupportedEncryption supportedEncryption = SupportedEncryption.getValue(enc);
        aesAlgorithm = CONTENT_ENCRYPTION.get(supportedEncryption);
    } catch (IllegalArgumentException e) {
        throw new JwtException("Unsupported content encryption: " + enc);
    }
    String decryptedPayload = new String(aesAlgorithm.decrypt(encryptionParts), StandardCharsets.UTF_8);
    return SignedJwt.parseToken(decryptedPayload);
}
Also used : PrivateKey(java.security.PrivateKey) JwkRSA(io.helidon.security.jwt.jwk.JwkRSA) Errors(io.helidon.common.Errors) JwkEC(io.helidon.security.jwt.jwk.JwkEC) Jwk(io.helidon.security.jwt.jwk.Jwk)

Aggregations

Errors (io.helidon.common.Errors)12 Test (org.junit.jupiter.api.Test)6 Jwk (io.helidon.security.jwt.jwk.Jwk)4 Jwt (io.helidon.security.jwt.Jwt)2 SignedJwt (io.helidon.security.jwt.SignedJwt)2 LinkedList (java.util.LinkedList)2 HelidonServiceLoader (io.helidon.common.serviceloader.HelidonServiceLoader)1 Config (io.helidon.config.Config)1 Configured (io.helidon.config.metadata.Configured)1 ConfiguredOption (io.helidon.config.metadata.ConfiguredOption)1 AuthorizationResponse (io.helidon.security.AuthorizationResponse)1 EndpointConfig (io.helidon.security.EndpointConfig)1 ProviderRequest (io.helidon.security.ProviderRequest)1 SecurityLevel (io.helidon.security.SecurityLevel)1 SecurityResponse (io.helidon.security.SecurityResponse)1 Subject (io.helidon.security.Subject)1 JwtException (io.helidon.security.jwt.JwtException)1 JwkEC (io.helidon.security.jwt.jwk.JwkEC)1 JwkRSA (io.helidon.security.jwt.jwk.JwkRSA)1 AbacValidator (io.helidon.security.providers.abac.spi.AbacValidator)1