Search in sources :

Example 6 with SignedJwt

use of io.helidon.security.jwt.SignedJwt 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 7 with SignedJwt

use of io.helidon.security.jwt.SignedJwt in project helidon by oracle.

the class JwtProvider method buildSubject.

Subject buildSubject(Jwt jwt, SignedJwt signedJwt) {
    Principal principal = buildPrincipal(jwt);
    TokenCredential.Builder builder = TokenCredential.builder();
    jwt.issueTime().ifPresent(builder::issueTime);
    jwt.expirationTime().ifPresent(builder::expTime);
    jwt.issuer().ifPresent(builder::issuer);
    builder.token(signedJwt.tokenContent());
    builder.addToken(Jwt.class, jwt);
    builder.addToken(SignedJwt.class, signedJwt);
    Subject.Builder subjectBuilder = Subject.builder().principal(principal).addPublicCredential(TokenCredential.class, builder.build());
    if (useJwtGroups) {
        Optional<List<String>> userGroups = jwt.userGroups();
        userGroups.ifPresent(groups -> groups.forEach(group -> subjectBuilder.addGrant(Role.create(group))));
    }
    Optional<List<String>> scopes = jwt.scopes();
    scopes.ifPresent(scopeList -> {
        scopeList.forEach(scope -> subjectBuilder.addGrant(Grant.builder().name(scope).type("scope").build()));
    });
    return subjectBuilder.build();
}
Also used : OutboundSecurityResponse(io.helidon.security.OutboundSecurityResponse) ProviderRequest(io.helidon.security.ProviderRequest) JwtException(io.helidon.security.jwt.JwtException) HashMap(java.util.HashMap) SignedJwt(io.helidon.security.jwt.SignedJwt) AuthenticationProvider(io.helidon.security.spi.AuthenticationProvider) Map(java.util.Map) Grant(io.helidon.security.Grant) Subject(io.helidon.security.Subject) TokenCredential(io.helidon.security.providers.common.TokenCredential) IdentityHashMap(java.util.IdentityHashMap) Config(io.helidon.config.Config) JwtUtil(io.helidon.security.jwt.JwtUtil) SubjectType(io.helidon.security.SubjectType) OutboundSecurityProvider(io.helidon.security.spi.OutboundSecurityProvider) SynchronousProvider(io.helidon.security.spi.SynchronousProvider) TokenHandler(io.helidon.security.util.TokenHandler) Instant(java.time.Instant) Logger(java.util.logging.Logger) Resource(io.helidon.common.configurable.Resource) AuthenticationResponse(io.helidon.security.AuthenticationResponse) OutboundConfig(io.helidon.security.providers.common.OutboundConfig) Principal(io.helidon.security.Principal) JwkKeys(io.helidon.security.jwt.jwk.JwkKeys) SecurityResponse(io.helidon.security.SecurityResponse) List(java.util.List) ChronoUnit(java.time.temporal.ChronoUnit) EndpointConfig(io.helidon.security.EndpointConfig) SecurityEnvironment(io.helidon.security.SecurityEnvironment) Jwt(io.helidon.security.jwt.Jwt) OutboundTarget(io.helidon.security.providers.common.OutboundTarget) Role(io.helidon.security.Role) Optional(java.util.Optional) Errors(io.helidon.common.Errors) Jwk(io.helidon.security.jwt.jwk.Jwk) List(java.util.List) TokenCredential(io.helidon.security.providers.common.TokenCredential) Principal(io.helidon.security.Principal) Subject(io.helidon.security.Subject)

Example 8 with SignedJwt

use of io.helidon.security.jwt.SignedJwt in project helidon by oracle.

the class JwtProviderTest method testEcBothWays.

@Test
public void testEcBothWays() {
    String username = "user1";
    String userId = "user1-id";
    String email = "user1@example.org";
    String familyName = "Novak";
    String givenName = "Standa";
    String fullName = "Standa Novak";
    Locale locale = Locale.CANADA_FRENCH;
    Principal principal = Principal.builder().name(username).id(userId).addAttribute("email", email).addAttribute("email_verified", true).addAttribute("family_name", familyName).addAttribute("given_name", givenName).addAttribute("full_name", fullName).addAttribute("locale", locale).build();
    Subject subject = Subject.create(principal);
    JwtProvider provider = JwtProvider.create(providersConfig.get("jwt"));
    SecurityContext context = Mockito.mock(SecurityContext.class);
    when(context.user()).thenReturn(Optional.of(subject));
    ProviderRequest request = mock(ProviderRequest.class);
    when(request.securityContext()).thenReturn(context);
    SecurityEnvironment outboundEnv = SecurityEnvironment.builder().path("/ec").transport("http").targetUri(URI.create("http://localhost:8080/ec")).build();
    EndpointConfig outboundEp = EndpointConfig.create();
    assertThat(provider.isOutboundSupported(request, outboundEnv, outboundEp), is(true));
    OutboundSecurityResponse response = provider.syncOutbound(request, outboundEnv, outboundEp);
    String signedToken = response.requestHeaders().get("Authorization").get(0);
    signedToken = signedToken.substring("bearer ".length());
    // now I want to validate it to prove it was correctly signed
    SignedJwt signedJwt = SignedJwt.parseToken(signedToken);
    signedJwt.verifySignature(verifyKeys).checkValid();
    Jwt jwt = signedJwt.getJwt();
    assertThat(jwt.subject(), is(Optional.of(userId)));
    assertThat(jwt.preferredUsername(), is(Optional.of(username)));
    assertThat(jwt.email(), is(Optional.of(email)));
    assertThat(jwt.emailVerified(), is(Optional.of(true)));
    assertThat(jwt.familyName(), is(Optional.of(familyName)));
    assertThat(jwt.givenName(), is(Optional.of(givenName)));
    assertThat(jwt.fullName(), is(Optional.of(fullName)));
    assertThat(jwt.locale(), is(Optional.of(locale)));
    assertThat(jwt.audience(), is(Optional.of(List.of("audience.application.id"))));
    assertThat(jwt.issuer(), is(Optional.of("jwt.example.com")));
    assertThat(jwt.algorithm(), is(Optional.of(JwkEC.ALG_ES256)));
    Instant instant = jwt.issueTime().get();
    boolean compareResult = Instant.now().minusSeconds(10).compareTo(instant) < 0;
    assertThat("Issue time must not be older than 10 seconds", compareResult, is(true));
    Instant expectedNotBefore = instant.minus(5, ChronoUnit.SECONDS);
    assertThat(jwt.notBefore(), is(Optional.of(expectedNotBefore)));
    Instant expectedExpiry = instant.plus(60 * 60 * 24, ChronoUnit.SECONDS);
    assertThat(jwt.expirationTime(), is(Optional.of(expectedExpiry)));
    // now we need to use the same token to invoke authentication
    ProviderRequest atnRequest = mock(ProviderRequest.class);
    SecurityEnvironment se = SecurityEnvironment.builder().header("Authorization", "bearer " + signedToken).build();
    when(atnRequest.env()).thenReturn(se);
    AuthenticationResponse authenticationResponse = provider.syncAuthenticate(atnRequest);
    authenticationResponse.user().map(Subject::principal).ifPresentOrElse(atnPrincipal -> {
        assertThat(atnPrincipal.id(), is(userId));
        assertThat(atnPrincipal.getName(), is(username));
        assertThat(atnPrincipal.abacAttribute("email"), is(Optional.of(email)));
        assertThat(atnPrincipal.abacAttribute("email_verified"), is(Optional.of(true)));
        assertThat(atnPrincipal.abacAttribute("family_name"), is(Optional.of(familyName)));
        assertThat(atnPrincipal.abacAttribute("given_name"), is(Optional.of(givenName)));
        assertThat(atnPrincipal.abacAttribute("full_name"), is(Optional.of(fullName)));
        assertThat(atnPrincipal.abacAttribute("locale"), is(Optional.of(locale)));
    }, () -> fail("User must be present in response"));
}
Also used : Locale(java.util.Locale) SecurityEnvironment(io.helidon.security.SecurityEnvironment) SignedJwt(io.helidon.security.jwt.SignedJwt) Jwt(io.helidon.security.jwt.Jwt) Instant(java.time.Instant) SignedJwt(io.helidon.security.jwt.SignedJwt) AuthenticationResponse(io.helidon.security.AuthenticationResponse) Subject(io.helidon.security.Subject) ProviderRequest(io.helidon.security.ProviderRequest) OutboundSecurityResponse(io.helidon.security.OutboundSecurityResponse) SecurityContext(io.helidon.security.SecurityContext) Principal(io.helidon.security.Principal) EndpointConfig(io.helidon.security.EndpointConfig) Test(org.junit.jupiter.api.Test)

Example 9 with SignedJwt

use of io.helidon.security.jwt.SignedJwt in project helidon by oracle.

the class OidcProvider method processValidationResult.

private AuthenticationResponse processValidationResult(ProviderRequest providerRequest, SignedJwt signedJwt, Errors.Collector collector) {
    Jwt jwt = signedJwt.getJwt();
    Errors errors = collector.collect();
    Errors validationErrors = jwt.validate(oidcConfig.issuer(), oidcConfig.audience());
    if (errors.isValid() && validationErrors.isValid()) {
        errors.log(LOGGER);
        Subject subject = buildSubject(jwt, signedJwt);
        Set<String> scopes = subject.grantsByType("scope").stream().map(Grant::getName).collect(Collectors.toSet());
        // make sure we have the correct scopes
        Set<String> expectedScopes = expectedScopes(providerRequest);
        List<String> missingScopes = new LinkedList<>();
        for (String expectedScope : expectedScopes) {
            if (!scopes.contains(expectedScope)) {
                missingScopes.add(expectedScope);
            }
        }
        if (missingScopes.isEmpty()) {
            return AuthenticationResponse.success(subject);
        } else {
            return errorResponse(providerRequest, Http.Status.FORBIDDEN_403, "insufficient_scope", "Scopes " + missingScopes + " are missing");
        }
    } else {
        if (LOGGER.isLoggable(Level.FINEST)) {
            // only log errors when details requested
            errors.log(LOGGER);
            validationErrors.log(LOGGER);
        }
        return errorResponse(providerRequest, Http.Status.UNAUTHORIZED_401, "invalid_token", "Token not valid");
    }
}
Also used : Errors(io.helidon.common.Errors) SignedJwt(io.helidon.security.jwt.SignedJwt) Jwt(io.helidon.security.jwt.Jwt) Subject(io.helidon.security.Subject) LinkedList(java.util.LinkedList)

Example 10 with SignedJwt

use of io.helidon.security.jwt.SignedJwt in project helidon by oracle.

the class Mp1Main method generateJwtToken.

private static String generateJwtToken() {
    Jwt jwt = Jwt.builder().subject("jack").addUserGroup("admin").addScope("admin_scope").algorithm(JwkRSA.ALG_RS256).issuer("native-image-mp1").audience("http://localhost:8087/jwt").issueTime(Instant.now()).userPrincipal("jack").keyId("SIGNING_KEY").expirationTime(Instant.now().plus(5, ChronoUnit.MINUTES)).build();
    JwkKeys jwkKeys = JwkKeys.builder().resource(Resource.create("sign-jwk.json")).build();
    SignedJwt signed = SignedJwt.sign(jwt, jwkKeys.forKeyId("sign-rsa").get());
    String tokenContent = signed.tokenContent();
    System.out.println("JWT token to use for /jwt requests: " + tokenContent);
    return tokenContent;
}
Also used : SignedJwt(io.helidon.security.jwt.SignedJwt) Jwt(io.helidon.security.jwt.Jwt) JwkKeys(io.helidon.security.jwt.jwk.JwkKeys) SignedJwt(io.helidon.security.jwt.SignedJwt)

Aggregations

SignedJwt (io.helidon.security.jwt.SignedJwt)22 Jwt (io.helidon.security.jwt.Jwt)20 Test (org.junit.jupiter.api.Test)13 Principal (io.helidon.security.Principal)12 Subject (io.helidon.security.Subject)11 AuthenticationResponse (io.helidon.security.AuthenticationResponse)10 EndpointConfig (io.helidon.security.EndpointConfig)10 OutboundSecurityResponse (io.helidon.security.OutboundSecurityResponse)10 ProviderRequest (io.helidon.security.ProviderRequest)10 SecurityEnvironment (io.helidon.security.SecurityEnvironment)10 SecurityContext (io.helidon.security.SecurityContext)8 JwtException (io.helidon.security.jwt.JwtException)7 Instant (java.time.Instant)7 HashMap (java.util.HashMap)6 List (java.util.List)6 Locale (java.util.Locale)6 Jwk (io.helidon.security.jwt.jwk.Jwk)5 IdentityHashMap (java.util.IdentityHashMap)5 Errors (io.helidon.common.Errors)4 JwkKeys (io.helidon.security.jwt.jwk.JwkKeys)4