diff --git a/pom.xml b/pom.xml
index c406a692e..9dabab446 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,7 +16,7 @@
1.12.2
5.11.2
- 9.2.0
+ 9.4.11
0.5.10
${project.version}
diff --git a/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java b/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java
index a5460644f..ead01877d 100644
--- a/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java
+++ b/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java
@@ -9,6 +9,8 @@
import io.vertx.ext.web.RoutingContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.uid2.shared.audit.AuditParams;
+import com.uid2.shared.audit.Audit;
import java.util.*;
@@ -17,6 +19,7 @@ public class AdminAuthMiddleware {
private final AuthProvider authProvider;
private final String environment;
private final boolean isAuthDisabled;
+ private final Audit audit;
final Map> roleToOktaGroups = new EnumMap<>(Role.class);
public AdminAuthMiddleware(AuthProvider authProvider, JsonObject config) {
@@ -26,6 +29,7 @@ public AdminAuthMiddleware(AuthProvider authProvider, JsonObject config) {
roleToOktaGroups.put(Role.MAINTAINER, parseOktaGroups(config.getString(AdminConst.ROLE_OKTA_GROUP_MAP_MAINTAINER)));
roleToOktaGroups.put(Role.PRIVILEGED, parseOktaGroups(config.getString(AdminConst.ROLE_OKTA_GROUP_MAP_PRIVILEGED)));
roleToOktaGroups.put(Role.SUPER_USER, parseOktaGroups(config.getString(AdminConst.ROLE_OKTA_GROUP_MAP_SUPER_USER)));
+ this.audit = new Audit(AdminAuthMiddleware.class.getPackage().getName());
}
private List parseOktaGroups(final String oktaGroups) {
@@ -40,15 +44,29 @@ private List parseOktaGroups(final String oktaGroups) {
return allOktaGroups;
}
- public Handler handle(Handler handler, Role... roles) {
+ public Handler handle(Handler handler, AuditParams params, Role... roles) {
if (isAuthDisabled) return handler;
if (roles == null || roles.length == 0) {
throw new IllegalArgumentException("must specify at least one role");
}
- AdminAuthHandler adminAuthHandler = new AdminAuthHandler(handler, authProvider, Set.of(roles), environment, roleToOktaGroups);
+ Handler loggedHandler = logAndHandle(handler, params);
+ AdminAuthHandler adminAuthHandler = new AdminAuthHandler(loggedHandler, authProvider, Set.of(roles),
+ environment, roleToOktaGroups);
return adminAuthHandler::handle;
}
+ public Handler handle(Handler handler, Role... roles) {
+ return this.handle(handler, new AuditParams(), roles);
+ }
+
+
+ private Handler logAndHandle(Handler handler, AuditParams params) {
+ return ctx -> {
+ ctx.addBodyEndHandler(v -> this.audit.log(ctx, params));
+ handler.handle(ctx);
+ };
+ }
+
private static class AdminAuthHandler {
private final String environment;
private final Handler innerHandler;
@@ -133,6 +151,10 @@ private void validateAccessToken(RoutingContext rc, String accessToken) {
return;
}
List scopes = (List) jwt.getClaims().get("scp");
+ JsonObject serviceAccountDetails = new JsonObject();
+ serviceAccountDetails.put("scope", scopes);
+ serviceAccountDetails.put("client_id", jwt.getClaims().get("client_id"));
+ rc.put("userDetails", serviceAccountDetails);
if(isAuthorizedService(scopes)) {
innerHandler.handle(rc);
} else {
@@ -154,6 +176,11 @@ private void validateIdToken(RoutingContext rc, String idToken) {
return;
}
List groups = (List) jwt.getClaims().get("groups");
+ JsonObject userDetails = new JsonObject();
+ userDetails.put("groups", groups);
+ userDetails.put("email", jwt.getClaims().get("email"));
+ userDetails.put("sub", jwt.getClaims().get("sub"));
+ rc.put("userDetails", userDetails);
if(isAuthorizedUser(groups)) {
innerHandler.handle(rc);
} else {
diff --git a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java
index 48a5509ca..46c68f2bb 100644
--- a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java
+++ b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java
@@ -9,6 +9,7 @@
import io.vertx.core.Handler;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
+import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.web.RoutingContext;
@@ -22,10 +23,11 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -67,6 +69,20 @@ public void setup() {
when(rc.response()).thenReturn(response);
when(rc.session()).thenReturn(session);
+ Map contextData = new HashMap<>();
+
+ when(rc.put(anyString(), any())).thenAnswer(invocation -> {
+ String key = invocation.getArgument(0);
+ Object value = invocation.getArgument(1);
+ contextData.put(key, value);
+ return rc; // Return rc for chaining
+ });
+
+ when(rc.get(anyString())).thenAnswer(invocation -> {
+ String key = invocation.getArgument(0);
+ return contextData.get(key);
+ });
+
when(response.setStatusCode(anyInt())).thenReturn(response);
when(response.putHeader(anyString(), anyString())).thenReturn(response);
}
@@ -151,7 +167,7 @@ public void testIdToken_GoodTokenUnauthorized() throws JwtVerificationException
handler.handle(rc);
verify(idTokenVerifier).decode(eq("testIdToken"), any());
- verify(jwt, times(3)).getClaims();
+ verify(jwt, times(5)).getClaims();
verifyUnauthorized(false);
}
@@ -173,7 +189,7 @@ public void testIdToken_GoodTokenRealRoleUnauthorized(List userOktaGroup
handler.handle(rc);
verify(idTokenVerifier).decode(eq("testIdToken"), any());
- verify(jwt, times(3)).getClaims();
+ verify(jwt, times(5)).getClaims();
verifyUnauthorized(false);
}
@@ -197,9 +213,13 @@ public void testIdToken_GoodTokenAuthorized(List userOktaGroups, Role...
Handler handler = adminAuthMiddleware.handle(innerHandler, endpointRoles);
handler.handle(rc);
-
+ JsonObject userDetails = rc.get("userDetails");
+ Set groups = userDetails.getJsonArray("groups").stream()
+ .map(Object::toString)
+ .collect(Collectors.toSet());
+ assertEquals(new HashSet<>(userOktaGroups), groups);
verify(idTokenVerifier).decode(eq("testIdToken"), any());
- verify(jwt, times(3)).getClaims();
+ verify(jwt, times(5)).getClaims();
verify(innerHandler).handle(eq(rc));
}
@@ -251,7 +271,7 @@ public void testAccessToken_GoodTokenUnauthorized(String customOktaScope, Role..
handler.handle(rc);
verify(accessTokenVerifier).decode(eq("testAccessToken"));
- verify(jwt, times(3)).getClaims();
+ verify(jwt, times(4)).getClaims();
verifyUnauthorized(false);
}
@@ -272,9 +292,14 @@ public void testAccessToken_GoodTokenAuthorized(OktaCustomScope scope, Role allo
Handler handler = adminAuthMiddleware.handle(innerHandler, allowedRole);
handler.handle(rc);
+ JsonObject userDetails = rc.get("userDetails");
+ Set scopes = userDetails.getJsonArray("scope").stream()
+ .map(Object::toString)
+ .collect(Collectors.toSet());
+ assertEquals(Set.of(scope.getName()), scopes);
verify(accessTokenVerifier).decode(eq("testAccessToken"));
- verify(jwt, times(3)).getClaims();
+ verify(jwt, times(4)).getClaims();
verify(innerHandler).handle(eq(rc));
}
}