diff --git a/src/main/java/com/redhat/ecosystemappeng/exploitiq/service/UserService.java b/src/main/java/com/redhat/ecosystemappeng/exploitiq/service/UserService.java index 344d6302..bf1b09a0 100644 --- a/src/main/java/com/redhat/ecosystemappeng/exploitiq/service/UserService.java +++ b/src/main/java/com/redhat/ecosystemappeng/exploitiq/service/UserService.java @@ -16,11 +16,13 @@ import io.quarkus.arc.properties.IfBuildProperty; import io.quarkus.oidc.UserInfo; +import io.quarkus.security.identity.SecurityIdentity; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Produces; import jakarta.inject.Inject; import jakarta.json.Json; import jakarta.json.JsonObject; +import org.eclipse.microprofile.jwt.JsonWebToken; import java.util.Objects; @ApplicationScoped @@ -29,6 +31,9 @@ public class UserService { @Inject UserInfo userInfo; + @Inject + SecurityIdentity securityIdentity; + private static final String DEFAULT_USERNAME = "anonymous"; @IfBuildProperty(name = "quarkus.oidc.enabled", stringValue = "false") @@ -42,12 +47,56 @@ public UserInfo getAnonymousUserInfo() { } /** - * Resolves the best available username from UserInfo claims. + * Resolves the best available username from JWT token claims or UserInfo. * - * Checks explicitly for: email, upn, metadata.name, preferred_username, sub. - * Falls back to "anonymous" if UserInfo is missing. + * Priority: + * 1. JWT token claims (email, cognito:username, username, upn, preferred_username, sub) + * 2. UserInfo (if available) + * 3. Falls back to "anonymous" */ public String getUserName() { + // First try to get username from JWT token directly + if (securityIdentity != null && securityIdentity.getPrincipal() instanceof JsonWebToken jwt) { + + + // Try email claim (Cognito ID tokens, common in OIDC) + String name = jwt.getClaim("email"); + if (Objects.nonNull(name) && !name.isBlank()) { + return name; + } + + // Try cognito:username (Cognito-specific) + name = jwt.getClaim("cognito:username"); + if (Objects.nonNull(name) && !name.isBlank()) { + return name; + } + + // Try username claim + name = jwt.getClaim("username"); + if (Objects.nonNull(name) && !name.isBlank()) { + return name; + } + + // Try upn (user principal name - common in enterprise) + name = jwt.getClaim("upn"); + if (Objects.nonNull(name) && !name.isBlank()) { + return name; + } + + // Try preferred_username (standard OIDC claim) + name = jwt.getClaim("preferred_username"); + if (Objects.nonNull(name) && !name.isBlank()) { + return name; + } + + // Try sub (subject - always present but may be UUID) + name = jwt.getClaim("sub"); + if (Objects.nonNull(name) && !name.isBlank()) { + return name; + } + } + + // Fallback to UserInfo if JWT extraction didn't work if (Objects.nonNull(userInfo)) { var name = userInfo.getString("email"); if (Objects.nonNull(name)) {