use of io.helidon.security.AuthenticationResponse in project helidon by oracle.
the class JwtAuthProviderTest 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).addAttribute("roles", Set.of("role1", "role2")).build();
Subject subject = Subject.builder().principal(principal).addGrant(Role.create("group1")).addGrant(Role.create("group2")).addGrant(Role.create("group3")).build();
JwtAuthProvider provider = JwtAuthProvider.create(Config.create().get("security.providers.0.mp-jwt-auth"));
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();
// MP specific additions
assertThat(jwt.payloadClaim("upn"), not(Optional.empty()));
assertThat(jwt.payloadClaim("groups"), not(Optional.empty()));
assertThat(jwt.userPrincipal(), is(Optional.of(username)));
assertThat(jwt.userGroups(), not(Optional.empty()));
assertThat(jwt.userGroups().get(), hasItems("group1", "group2", "group3"));
// End of MP specific additions
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 = mockRequest(signedToken);
AuthenticationResponse authenticationResponse = provider.syncAuthenticate(atnRequest);
authenticationResponse.user().map(Subject::principal).ifPresentOrElse(atnPrincipal -> {
assertThat(atnPrincipal, instanceOf(JsonWebTokenImpl.class));
JsonWebTokenImpl jsonWebToken = (JsonWebTokenImpl) atnPrincipal;
String upn = jsonWebToken.getClaim(Claims.upn.name());
assertThat(upn, is(username));
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.AuthenticationResponse in project helidon by oracle.
the class SecurityFilterCommon method processAuthentication.
protected void processAuthentication(FilterContext context, SecurityClientBuilder<AuthenticationResponse> clientBuilder, SecurityDefinition methodSecurity, AtnTracing atnTracing) {
AuthenticationResponse response = clientBuilder.buildAndGet();
SecurityResponse.SecurityStatus responseStatus = response.status();
atnTracing.logStatus(responseStatus);
switch(responseStatus) {
case SUCCESS:
// everything is fine, we can continue with processing
return;
case FAILURE_FINISH:
if (methodSecurity.authenticationOptional()) {
logger().finest("Authentication failed, but was optional, so assuming anonymous");
} else {
context.setTraceSuccess(false);
context.setTraceDescription(response.description().orElse(responseStatus.toString()));
context.setTraceThrowable(response.throwable().orElse(null));
context.setShouldFinish(true);
int status = response.statusCode().orElse(Response.Status.UNAUTHORIZED.getStatusCode());
abortRequest(context, response, status, Map.of());
}
return;
case SUCCESS_FINISH:
context.setShouldFinish(true);
int status = response.statusCode().orElse(Response.Status.OK.getStatusCode());
abortRequest(context, response, status, Map.of());
return;
case ABSTAIN:
if (methodSecurity.authenticationOptional()) {
logger().finest("Authentication failed, but was optional, so assuming anonymous");
} else {
context.setTraceSuccess(false);
context.setTraceDescription(response.description().orElse(responseStatus.toString()));
context.setShouldFinish(true);
abortRequest(context, response, Response.Status.UNAUTHORIZED.getStatusCode(), Map.of());
}
return;
case FAILURE:
if (methodSecurity.authenticationOptional() && !methodSecurity.failOnFailureIfOptional()) {
logger().finest("Authentication failed, but was optional, so assuming anonymous");
} else {
context.setTraceDescription(response.description().orElse(responseStatus.toString()));
context.setTraceThrowable(response.throwable().orElse(null));
context.setTraceSuccess(false);
abortRequest(context, response, Response.Status.UNAUTHORIZED.getStatusCode(), Map.of());
context.setShouldFinish(true);
}
return;
default:
context.setTraceSuccess(false);
context.setTraceDescription(response.description().orElse("UNKNOWN_RESPONSE: " + responseStatus));
context.setShouldFinish(true);
SecurityException throwable = new SecurityException("Invalid SecurityStatus returned: " + responseStatus);
context.setTraceThrowable(throwable);
throw throwable;
}
}
use of io.helidon.security.AuthenticationResponse in project helidon by oracle.
the class OptionalSecurityTest method init.
@BeforeAll
static void init() {
/*
* Prepare parameters
*/
security = Security.builder().addAuthenticationProvider(OptionalSecurityTest::authenticate).build();
featureConfig = new FeatureConfig();
serverConfig = ResourceConfig.forApplication(getApplication());
AuthenticationResponse atr = AuthenticationResponse.builder().status(SecurityResponse.SecurityStatus.FAILURE_FINISH).statusCode(301).build();
clientBuilder = mock(SecurityClientBuilder.class);
when(clientBuilder.buildAndGet()).thenReturn(atr);
tracing = SecurityTracing.get();
}
use of io.helidon.security.AuthenticationResponse in project helidon by oracle.
the class SecurityFilterTest method testAtnThrowException.
@Test
void testAtnThrowException() {
SecurityFeature feature = SecurityFeature.builder(security).useAbortWith(false).build();
SecurityContext securityContext = security.createContext("testNotAbortWith");
SecurityFilter sf = new SecurityFilter(feature.featureConfig(), security, serverConfig, securityContext);
ContainerRequest request = mock(ContainerRequest.class);
SecurityFilter.FilterContext filterContext = new SecurityFilter.FilterContext();
filterContext.setJerseyRequest(request);
SecurityDefinition methodSecurity = mock(SecurityDefinition.class);
SecurityClientBuilder<AuthenticationResponse> clientBuilder = mock(SecurityClientBuilder.class);
when(clientBuilder.buildAndGet()).thenReturn(AuthenticationResponse.failed("Unit-test"));
WebApplicationException e = Assertions.assertThrows(WebApplicationException.class, () -> sf.processAuthentication(filterContext, clientBuilder, methodSecurity, tracing.atnTracing()));
Response response = e.getResponse();
String message = e.getMessage();
assertThat(response.getStatus(), is(401));
assertThat(message, is("Unit-test"));
}
use of io.helidon.security.AuthenticationResponse in project helidon by oracle.
the class GoogleTokenProvider method syncAuthenticate.
@Override
protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) {
Optional<String> maybeToken;
try {
maybeToken = tokenHandler.extractToken(providerRequest.env().headers());
} catch (Exception e) {
return failInvalidRequest(e);
}
SecurityContext sContext = providerRequest.securityContext();
return maybeToken.map(token -> cachedResponse(token, sContext.tracer(), sContext.tracingSpan())).orElseGet(this::failNoToken);
}
Aggregations