use of io.helidon.security.SecurityEnvironment 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.SecurityEnvironment in project helidon by oracle.
the class JwtAuthTest method testRsa.
@Test
void testRsa() {
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);
JwtAuthProvider provider = JwtAuthProvider.create(Config.create().get("security.providers.0.mp-jwt-auth"));
io.helidon.security.SecurityContext context = Mockito.mock(io.helidon.security.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);
// authenticated
String httpResponse = target.path("/hello").request().header("Authorization", signedToken).get(String.class);
assertThat(httpResponse, is("Hello user1"));
httpResponse = target.path("/public").path("/hello").request().header("Authorization", signedToken).get(String.class);
assertThat(httpResponse, is("Hello user1"));
}
use of io.helidon.security.SecurityEnvironment in project helidon by oracle.
the class JakartaElPolicyExecutorTest method testSimpleExpression.
@Test
public void testSimpleExpression() {
JavaxElPolicyExecutor ex = JavaxElPolicyExecutor.create();
SecurityEnvironment env = SecurityEnvironment.create();
Subject user = Subject.builder().principal(Principal.create("unit-test-user")).addGrant(Role.create("unit-test-user-role")).build();
Subject service = Subject.builder().principal(Principal.create("unit-test-service")).addGrant(Role.create("unit-test-service-role")).build();
MyResource object = new MyResource("unit-test-user");
ProviderRequest request = mock(ProviderRequest.class);
when(request.service()).thenReturn(Optional.of(service));
when(request.subject()).thenReturn(Optional.of(user));
when(request.env()).thenReturn(env);
when(request.getObject()).thenReturn(Optional.of(object));
Errors.Collector collector = Errors.collector();
ex.executePolicy("${user.principal.id == object.owner}", collector, request);
collector.collect().checkValid();
collector = Errors.collector();
ex.executePolicy("${user.principal.id == object.owner}", collector, request);
collector.collect().checkValid();
collector = Errors.collector();
ex.executePolicy("${inRole(user, 'unit-test-user-role') && inRole(service, 'unit-test-service-role')}", collector, request);
collector.collect().checkValid();
collector = Errors.collector();
ex.executePolicy("${service.principal.id == object.owner}", collector, request);
if (collector.collect().isValid()) {
fail("Should have failed, as service is not the owner of the object");
}
collector = Errors.collector();
ex.executePolicy("${env.time.year >= 2017}", collector, request);
collector.collect().checkValid();
}
use of io.helidon.security.SecurityEnvironment in project helidon by oracle.
the class SecurityFilterCommon method doFilter.
protected void doFilter(ContainerRequestContext request, SecurityContext securityContext) {
SecurityTracing tracing = SecurityTracing.get();
tracing.securityContext(securityContext);
SecurityFilter.FilterContext filterContext = initRequestFiltering(request);
if (filterContext.isShouldFinish()) {
// 404
tracing.finish();
return;
}
URI requestUri = request.getUriInfo().getRequestUri();
String query = requestUri.getQuery();
String origRequest;
if ((null == query) || query.isEmpty()) {
origRequest = requestUri.getPath();
} else {
origRequest = requestUri.getPath() + "?" + query;
}
Map<String, List<String>> allHeaders = new HashMap<>(filterContext.getHeaders());
allHeaders.put(Security.HEADER_ORIG_URI, List.of(origRequest));
SecurityEnvironment.Builder envBuilder = SecurityEnvironment.builder(security.serverTime()).path(filterContext.getResourcePath()).targetUri(filterContext.getTargetUri()).method(filterContext.getMethod()).headers(allHeaders).addAttribute("resourceType", filterContext.getResourceName());
// The following two lines are not possible in JAX-RS or Jersey - we would have to touch
// underlying web server's request...
String remoteHost = (String) request.getProperty("io.helidon.jaxrs.remote-host");
Integer remotePort = (Integer) request.getProperty("io.helidon.jaxrs.remote-port");
if (remoteHost != null) {
envBuilder.addAttribute("userIp", remoteHost);
}
if (remotePort != null) {
envBuilder.addAttribute("userPort", remotePort);
}
SecurityEnvironment env = envBuilder.build();
EndpointConfig ec = EndpointConfig.builder().securityLevels(filterContext.getMethodSecurity().getSecurityLevels()).build();
try {
securityContext.env(env);
securityContext.endpointConfig(ec);
request.setProperty(PROP_FILTER_CONTEXT, filterContext);
// context is needed even if authn/authz fails - for auditing
request.setSecurityContext(new JerseySecurityContext(securityContext, filterContext.getMethodSecurity(), "https".equals(filterContext.getTargetUri().getScheme())));
processSecurity(request, filterContext, tracing, securityContext);
} finally {
if (filterContext.isTraceSuccess()) {
tracing.logProceed();
tracing.finish();
} else {
tracing.logDeny();
tracing.error("aborted");
}
}
}
use of io.helidon.security.SecurityEnvironment in project helidon by oracle.
the class GrpcSecurity method registerContext.
@SuppressWarnings("unchecked")
<ReqT, RespT> Context registerContext(ServerCall<ReqT, RespT> call, Metadata headers) {
Context grpcContext;
if (SECURITY_CONTEXT.get() == null) {
SocketAddress remoteSocket = call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR);
String address = null;
int port = -1;
if (remoteSocket instanceof InetSocketAddress) {
address = ((InetSocketAddress) remoteSocket).getHostName();
port = ((InetSocketAddress) remoteSocket).getPort();
} else {
address = String.valueOf(remoteSocket);
}
Map<String, List<String>> headerMap = new HashMap<>();
Map mapExtra = CONTEXT_ADD_HEADERS.get();
if (mapExtra != null) {
headerMap.putAll(mapExtra);
}
for (String name : headers.keys()) {
Metadata.Key key = Metadata.Key.of(name, Metadata.ASCII_STRING_MARSHALLER);
Iterable<Object> iterable = headers.getAll(key);
List<String> values = new ArrayList<>();
if (iterable != null) {
for (Object o : iterable) {
values.add(String.valueOf(o));
}
}
headerMap.put(name, values);
}
MethodDescriptor<ReqT, RespT> methodDescriptor = call.getMethodDescriptor();
String methodName = methodDescriptor.getFullMethodName();
SecurityEnvironment env = security.environmentBuilder().path(methodName).method(methodName).headers(headerMap).addAttribute(ABAC_ATTRIBUTE_REMOTE_ADDRESS, address).addAttribute(ABAC_ATTRIBUTE_REMOTE_PORT, port).addAttribute(ABAC_ATTRIBUTE_HEADERS, headers).addAttribute(ABAC_ATTRIBUTE_METHOD, methodDescriptor).transport("grpc").build();
EndpointConfig ec = EndpointConfig.builder().build();
Span span = OpenTracingContextKey.getKey().get();
SpanContext spanContext = span == null ? null : span.context();
SecurityContext context = security.contextBuilder(String.valueOf(SECURITY_COUNTER.incrementAndGet())).tracingSpan(spanContext).env(env).endpointConfig(ec).build();
Contexts.context().ifPresent(ctx -> ctx.register(context));
grpcContext = Context.current().withValue(SECURITY_CONTEXT, context);
} else {
grpcContext = Context.current();
}
return grpcContext;
}
Aggregations