Search in sources :

Example 1 with Jwk

use of io.helidon.security.jwt.jwk.Jwk in project helidon by oracle.

the class SignedJwtTest method testSignatureNone.

@Test
public void testSignatureNone() {
    Jwt jwt = Jwt.builder().algorithm("none").issuer("unit-test").build();
    Jwk defaultJwk = Jwk.NONE_JWK;
    SignedJwt signed = SignedJwt.sign(jwt, customKeys);
    assertThat(signed, notNullValue());
    assertThat(signed.getSignature(), notNullValue());
    assertThat(signed.getSignature(), is(new byte[0]));
    Errors errors = signed.verifySignature(customKeys, defaultJwk);
    assertThat(errors, notNullValue());
    errors.log(LOGGER);
    errors.checkValid();
}
Also used : Errors(io.helidon.common.Errors) Jwk(io.helidon.security.jwt.jwk.Jwk) Test(org.junit.jupiter.api.Test)

Example 2 with Jwk

use of io.helidon.security.jwt.jwk.Jwk in project helidon by oracle.

the class SignedJwt method verifySignature.

/**
 * Verify signature against the provided keys (the kid of thisPrincipal
 * JWT should be present in the {@link JwkKeys} provided).
 *
 * @param keys       JwkKeys to obtain a key to verify signature
 * @param defaultJwk Default value of JWK
 * @return Errors with collected messages, see {@link Errors#isValid()} and {@link Errors#checkValid()}
 */
public Errors verifySignature(JwkKeys keys, Jwk defaultJwk) {
    Errors.Collector collector = Errors.collector();
    String alg = headers.algorithm().orElse(null);
    String kid = headers.keyId().orElse(null);
    Jwk jwk = null;
    boolean jwtWithoutKidAndNoneAlg = false;
    // TODO support multiple JWK under same kid if different alg (see if spec allows this)
    if (null == alg) {
        if (null == kid) {
            if (defaultJwk == null) {
                jwtWithoutKidAndNoneAlg = true;
                jwk = Jwk.NONE_JWK;
            } else {
                jwk = defaultJwk;
            }
            alg = jwk.algorithm();
        } else {
            // null alg, non-null kid - will use alg of jwk
            jwk = keys.forKeyId(kid).orElse(null);
            if (null == jwk) {
                if (null == defaultJwk) {
                    collector.fatal(keys, "Key for key id: " + kid + " not found");
                } else {
                    jwk = defaultJwk;
                }
            }
            if (null != jwk) {
                alg = jwk.algorithm();
            }
        }
    } else {
        // alg not null
        if (null == kid) {
            if (Jwk.ALG_NONE.equals(alg)) {
                if (null != defaultJwk) {
                    if (defaultJwk.algorithm().equals(alg)) {
                    // yes, we expect none algorithm
                    } else {
                        collector.fatal("Algorithm is " + alg + ", default jwk requires " + defaultJwk.algorithm());
                    }
                } else {
                    jwk = Jwk.NONE_JWK;
                    jwtWithoutKidAndNoneAlg = true;
                }
            } else {
                jwk = defaultJwk;
                if (null == jwk) {
                    collector.fatal("Algorithm is " + alg + ", yet no kid is defined in JWT header, cannot validate");
                }
            }
        } else {
            // both not null
            jwk = keys.forKeyId(kid).orElse(null);
            if (null == jwk) {
                if ((null != defaultJwk) && alg.equals(defaultJwk.algorithm())) {
                    jwk = defaultJwk;
                }
                if (null == jwk) {
                    collector.fatal(keys, "Key for key id: " + kid + " not found");
                }
            }
        }
    }
    if (null == jwk) {
        return collector.collect();
    }
    if (jwtWithoutKidAndNoneAlg) {
        collector.fatal(jwk, "None algorithm not allowed, unless specified as the default JWK");
    }
    // now if jwk algorithm is none, alg may be
    if (jwk.algorithm().equals(alg)) {
        try {
            if (!jwk.verifySignature(signedBytes, signature)) {
                collector.fatal(jwk, "Signature of JWT token is not valid, based on alg: " + alg + ", kid: " + kid);
            }
        } catch (Exception e) {
            collector.fatal(jwk, "Failed to verify signature due to an exception: " + e.getClass().getName() + ": " + e.getMessage());
        }
    } else {
        collector.fatal(jwk, "Algorithm of JWK (" + jwk.algorithm() + ") does not match algorithm of this JWT (" + alg + ") for kid: " + kid);
    }
    return collector.collect();
}
Also used : Errors(io.helidon.common.Errors) Jwk(io.helidon.security.jwt.jwk.Jwk)

Example 3 with Jwk

use of io.helidon.security.jwt.jwk.Jwk in project helidon by oracle.

the class JwtProvider method impersonate.

private OutboundSecurityResponse impersonate(JwtOutboundTarget ot, String username) {
    Map<String, List<String>> headers = new HashMap<>();
    Jwk jwk = signKeys.forKeyId(ot.jwkKid).orElseThrow(() -> new JwtException("Signing JWK with kid: " + ot.jwkKid + " is not defined."));
    Jwt.Builder builder = Jwt.builder();
    builder.addPayloadClaim("name", username);
    builder.subject(username).preferredUsername(username).issuer(issuer).algorithm(jwk.algorithm());
    ot.update(builder);
    Jwt jwt = builder.build();
    SignedJwt signed = SignedJwt.sign(jwt, jwk);
    ot.outboundHandler.header(headers, signed.tokenContent());
    return OutboundSecurityResponse.withHeaders(headers);
}
Also used : HashMap(java.util.HashMap) IdentityHashMap(java.util.IdentityHashMap) SignedJwt(io.helidon.security.jwt.SignedJwt) Jwt(io.helidon.security.jwt.Jwt) List(java.util.List) JwtException(io.helidon.security.jwt.JwtException) SignedJwt(io.helidon.security.jwt.SignedJwt) Jwk(io.helidon.security.jwt.jwk.Jwk)

Example 4 with Jwk

use of io.helidon.security.jwt.jwk.Jwk in project helidon by oracle.

the class SignedJwtTest method testSingatureNoAlgNoKid.

@Test
public void testSingatureNoAlgNoKid() {
    Jwt jwt = Jwt.builder().build();
    Jwk defaultJwk = Jwk.NONE_JWK;
    SignedJwt signed = SignedJwt.sign(jwt, customKeys);
    assertThat(signed, notNullValue());
    assertThat(signed.getSignature(), notNullValue());
    assertThat(signed.getSignature(), is(new byte[0]));
    Errors errors = signed.verifySignature(customKeys, defaultJwk);
    assertThat(errors, notNullValue());
    errors.log(LOGGER);
    errors.checkValid();
}
Also used : Errors(io.helidon.common.Errors) Jwk(io.helidon.security.jwt.jwk.Jwk) Test(org.junit.jupiter.api.Test)

Example 5 with Jwk

use of io.helidon.security.jwt.jwk.Jwk in project helidon by oracle.

the class JwtProvider method propagate.

private OutboundSecurityResponse propagate(JwtOutboundTarget ot, Subject subject) {
    Map<String, List<String>> headers = new HashMap<>();
    Jwk jwk = signKeys.forKeyId(ot.jwkKid).orElseThrow(() -> new JwtException("Signing JWK with kid: " + ot.jwkKid + " is not defined."));
    Principal principal = subject.principal();
    Jwt.Builder builder = Jwt.builder();
    principal.abacAttributeNames().forEach(name -> {
        principal.abacAttribute(name).ifPresent(val -> builder.addPayloadClaim(name, val));
    });
    principal.abacAttribute("full_name").ifPresentOrElse(name -> builder.addPayloadClaim("name", name), () -> builder.removePayloadClaim("name"));
    builder.subject(principal.id()).preferredUsername(principal.getName()).issuer(issuer).algorithm(jwk.algorithm());
    ot.update(builder);
    Jwt jwt = builder.build();
    SignedJwt signed = SignedJwt.sign(jwt, jwk);
    ot.outboundHandler.header(headers, signed.tokenContent());
    return OutboundSecurityResponse.withHeaders(headers);
}
Also used : HashMap(java.util.HashMap) IdentityHashMap(java.util.IdentityHashMap) SignedJwt(io.helidon.security.jwt.SignedJwt) Jwt(io.helidon.security.jwt.Jwt) List(java.util.List) JwtException(io.helidon.security.jwt.JwtException) SignedJwt(io.helidon.security.jwt.SignedJwt) Principal(io.helidon.security.Principal) Jwk(io.helidon.security.jwt.jwk.Jwk)

Aggregations

Jwk (io.helidon.security.jwt.jwk.Jwk)8 Errors (io.helidon.common.Errors)4 Jwt (io.helidon.security.jwt.Jwt)4 JwtException (io.helidon.security.jwt.JwtException)4 SignedJwt (io.helidon.security.jwt.SignedJwt)4 HashMap (java.util.HashMap)4 IdentityHashMap (java.util.IdentityHashMap)4 List (java.util.List)4 Principal (io.helidon.security.Principal)2 EncryptedJwt (io.helidon.security.jwt.EncryptedJwt)2 LinkedList (java.util.LinkedList)2 Test (org.junit.jupiter.api.Test)2 JwkEC (io.helidon.security.jwt.jwk.JwkEC)1 JwkRSA (io.helidon.security.jwt.jwk.JwkRSA)1 PrivateKey (java.security.PrivateKey)1