use of io.helidon.security.Principal in project helidon by oracle.
the class HeaderAtnProvider method syncOutbound.
@Override
protected OutboundSecurityResponse syncOutbound(ProviderRequest providerRequest, SecurityEnvironment outboundEnv, EndpointConfig outboundEndpointConfig) {
Optional<Subject> toPropagate;
if (subjectType == SubjectType.USER) {
toPropagate = providerRequest.securityContext().user();
} else {
toPropagate = providerRequest.securityContext().service();
}
// find the target
var target = outboundConfig.findTargetCustomObject(outboundEnv, HeaderAtnOutboundConfig.class, HeaderAtnOutboundConfig::create, HeaderAtnOutboundConfig::create);
// we have no target, let's fall back to original behavior
if (target.isEmpty()) {
if (outboundTokenHandler != null) {
return toPropagate.map(Subject::principal).map(Principal::id).map(id -> respond(outboundEnv, outboundTokenHandler, id)).orElseGet(OutboundSecurityResponse::abstain);
}
return OutboundSecurityResponse.abstain();
}
// we found a target
HeaderAtnOutboundConfig outboundConfig = target.get();
TokenHandler tokenHandler = outboundConfig.tokenHandler().orElse(defaultOutboundTokenHandler);
return outboundConfig.explicitUser().or(() -> toPropagate.map(Subject::principal).map(Principal::id)).map(id -> respond(outboundEnv, tokenHandler, id)).orElseGet(OutboundSecurityResponse::abstain);
}
use of io.helidon.security.Principal in project helidon by oracle.
the class OidcProvider method buildPrincipal.
private Principal buildPrincipal(Jwt jwt) {
String subject = jwt.subject().orElseThrow(() -> new JwtException("JWT does not contain subject claim, cannot create principal."));
String name = jwt.preferredUsername().orElse(subject);
Principal.Builder builder = Principal.builder();
builder.name(name).id(subject);
jwt.payloadClaims().forEach((key, jsonValue) -> builder.addAttribute(key, JwtUtil.toObject(jsonValue)));
jwt.email().ifPresent(value -> builder.addAttribute("email", value));
jwt.emailVerified().ifPresent(value -> builder.addAttribute("email_verified", value));
jwt.locale().ifPresent(value -> builder.addAttribute("locale", value));
jwt.familyName().ifPresent(value -> builder.addAttribute("family_name", value));
jwt.givenName().ifPresent(value -> builder.addAttribute("given_name", value));
jwt.fullName().ifPresent(value -> builder.addAttribute("full_name", value));
return builder.build();
}
use of io.helidon.security.Principal 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.Principal 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.Principal 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"));
}
Aggregations