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"));
}
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();
}
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"));
}
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"));
}
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);
}
Aggregations