use of io.helidon.security.jwt.Jwt 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);
}
use of io.helidon.security.jwt.Jwt 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();
}
use of io.helidon.security.jwt.Jwt 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"));
}
use of io.helidon.security.jwt.Jwt 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");
}
}
use of io.helidon.security.jwt.Jwt 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;
}
Aggregations