Search in sources :

Example 11 with Jwt

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

the class Gh3246Test method testSecuredCallout.

@Test
void testSecuredCallout() {
    Jwt jwt = Jwt.builder().subject("jack").addUserGroup("admin").algorithm(JwkRSA.ALG_RS256).issuer("test-gh-3246").audience("http://example.helidon.io").issueTime(Instant.now()).userPrincipal("jack").keyId("SIGNING_KEY").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();
    int port = webTarget.getUri().getPort();
    String response = webTarget.path("/test/secured").queryParam("port", port).request().header(Http.Header.AUTHORIZATION, "Bearer " + tokenContent).get(String.class);
    assertThat(response, is("hello"));
}
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) HelidonTest(io.helidon.microprofile.tests.junit5.HelidonTest) Test(org.junit.jupiter.api.Test)

Example 12 with Jwt

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

the class OidcProvider method buildSubject.

private 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 : Arrays(java.util.Arrays) Security(io.helidon.security.Security) JwtException(io.helidon.security.jwt.JwtException) BiFunction(java.util.function.BiFunction) DeprecatedConfig(io.helidon.config.DeprecatedConfig) MediaType(io.helidon.common.http.MediaType) ScopeValidator(io.helidon.security.abac.scope.ScopeValidator) Matcher(java.util.regex.Matcher) Map(java.util.Map) FormParams(io.helidon.common.http.FormParams) Grant(io.helidon.security.Grant) ConfiguredOption(io.helidon.config.metadata.ConfiguredOption) SecurityLevel(io.helidon.security.SecurityLevel) JwtUtil(io.helidon.security.jwt.JwtUtil) Collection(java.util.Collection) Set(java.util.Set) UUID(java.util.UUID) Logger(java.util.logging.Logger) AuthenticationResponse(io.helidon.security.AuthenticationResponse) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) Role(io.helidon.security.Role) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) Errors(io.helidon.common.Errors) OutboundSecurityResponse(io.helidon.security.OutboundSecurityResponse) ProviderRequest(io.helidon.security.ProviderRequest) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Level(java.util.logging.Level) HashSet(java.util.HashSet) SignedJwt(io.helidon.security.jwt.SignedJwt) OidcCookieHandler(io.helidon.security.providers.oidc.common.OidcCookieHandler) AuthenticationProvider(io.helidon.security.spi.AuthenticationProvider) OidcConfig(io.helidon.security.providers.oidc.common.OidcConfig) BiConsumer(java.util.function.BiConsumer) Single(io.helidon.common.reactive.Single) Subject(io.helidon.security.Subject) TokenCredential(io.helidon.security.providers.common.TokenCredential) LinkedList(java.util.LinkedList) Http(io.helidon.common.http.Http) Config(io.helidon.config.Config) OutboundSecurityProvider(io.helidon.security.spi.OutboundSecurityProvider) Configured(io.helidon.config.metadata.Configured) SecurityProvider(io.helidon.security.spi.SecurityProvider) OidcConfig.postJsonResponse(io.helidon.security.providers.oidc.common.OidcConfig.postJsonResponse) TokenHandler(io.helidon.security.util.TokenHandler) OutboundConfig(io.helidon.security.providers.common.OutboundConfig) Principal(io.helidon.security.Principal) JwkKeys(io.helidon.security.jwt.jwk.JwkKeys) SecurityResponse(io.helidon.security.SecurityResponse) URLEncoder(java.net.URLEncoder) EndpointConfig(io.helidon.security.EndpointConfig) SecurityEnvironment(io.helidon.security.SecurityEnvironment) Jwt(io.helidon.security.jwt.Jwt) OutboundTarget(io.helidon.security.providers.common.OutboundTarget) WebClientRequestBuilder(io.helidon.webclient.WebClientRequestBuilder) List(java.util.List) LinkedList(java.util.LinkedList) TokenCredential(io.helidon.security.providers.common.TokenCredential) Principal(io.helidon.security.Principal) Subject(io.helidon.security.Subject)

Example 13 with Jwt

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

the class JwtProviderTest method testRsaBothWays.

@Test
public void testRsaBothWays() {
    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("/rsa").transport("http").targetUri(URI.create("http://localhost:8080/rsa")).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(JwkRSA.ALG_RS256)));
    assertThat(jwt.issueTime(), is(not(Optional.empty())));
    jwt.issueTime().ifPresent(instant -> {
        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(60, ChronoUnit.SECONDS);
        assertThat(jwt.notBefore(), is(Optional.of(expectedNotBefore)));
        Instant expectedExpiry = instant.plus(3600, 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 14 with Jwt

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

the class JwtProviderTest method testOctBothWays.

@Test
public void testOctBothWays() {
    String userId = "user1-id";
    Principal tp = Principal.create(userId);
    Subject subject = Subject.create(tp);
    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("/oct").transport("http").targetUri(URI.create("http://localhost:8080/oct")).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(userId)));
    assertThat(jwt.email(), is(Optional.empty()));
    assertThat(jwt.emailVerified(), is(Optional.empty()));
    assertThat(jwt.familyName(), is(Optional.empty()));
    assertThat(jwt.givenName(), is(Optional.empty()));
    // stored as "name" attribute on principal, full name is stored as "name" in JWT
    assertThat(jwt.fullName(), is(Optional.empty()));
    assertThat(jwt.locale(), is(Optional.empty()));
    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(JwkOctet.ALG_HS256)));
    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(userId));
        assertThat(atnPrincipal.abacAttribute("email"), is(Optional.empty()));
        assertThat(atnPrincipal.abacAttribute("email_verified"), is(Optional.empty()));
        assertThat(atnPrincipal.abacAttribute("family_name"), is(Optional.empty()));
        assertThat(atnPrincipal.abacAttribute("given_name"), is(Optional.empty()));
        assertThat(atnPrincipal.abacAttribute("full_name"), is(Optional.empty()));
        assertThat(atnPrincipal.abacAttribute("locale"), is(Optional.empty()));
    }, () -> fail("User must be present in response"));
}
Also used : 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 15 with Jwt

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

Jwt (io.helidon.security.jwt.Jwt)20 SignedJwt (io.helidon.security.jwt.SignedJwt)20 Test (org.junit.jupiter.api.Test)11 Principal (io.helidon.security.Principal)10 Subject (io.helidon.security.Subject)9 AuthenticationResponse (io.helidon.security.AuthenticationResponse)8 EndpointConfig (io.helidon.security.EndpointConfig)8 OutboundSecurityResponse (io.helidon.security.OutboundSecurityResponse)8 ProviderRequest (io.helidon.security.ProviderRequest)8 SecurityEnvironment (io.helidon.security.SecurityEnvironment)8 JwtException (io.helidon.security.jwt.JwtException)7 Instant (java.time.Instant)7 SecurityContext (io.helidon.security.SecurityContext)6 HashMap (java.util.HashMap)6 List (java.util.List)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 LinkedList (java.util.LinkedList)4