Skip to content

Commit

Permalink
Add error details to events to be able to track down root causes
Browse files Browse the repository at this point in the history
Closes #28429

Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
  • Loading branch information
ahus1 committed Apr 16, 2024
1 parent a5161f4 commit 261b689
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,8 @@ final protected BrokeredIdentityContext validateJwt(EventBuilder event, String s
return context;
} catch (IOException e) {
logger.debug("Unable to extract identity from identity token", e);
event.detail(Details.REASON, "Unable to extract identity from identity token: " + e.getMessage());
event.error(Errors.INVALID_TOKEN);
throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token", Response.Status.BAD_REQUEST);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ private void logEvent(Event event) {
sanitize(sb, event.getClientId());
sb.append(", userId=");
sanitize(sb, event.getUserId());
if (event.getSessionId() != null) {
sb.append(", sessionId=");
sanitize(sb, event.getSessionId());
}
sb.append(", ipAddress=");
sanitize(sb, event.getIpAddress());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1149,8 +1149,9 @@ private void generateRefreshToken(boolean offlineTokenRequested) {
if (offlineTokenRequested) {
UserSessionManager sessionManager = new UserSessionManager(session);
if (!sessionManager.isOfflineTokenAllowed(clientSessionCtx)) {
event.detail(Details.REASON, "Offline tokens not allowed for the user or client");
event.error(Errors.NOT_ALLOWED);
throw new ErrorResponseException("not_allowed", "Offline tokens not allowed for the user or client", Response.Status.BAD_REQUEST);
throw new ErrorResponseException(Errors.NOT_ALLOWED, "Offline tokens not allowed for the user or client", Response.Status.BAD_REQUEST);
}
refreshToken.type(TokenUtil.TOKEN_TYPE_OFFLINE);
if (realm.isOfflineSessionMaxLifespanEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ private Response doBrowserLogout(AuthenticationSessionModel logoutSession) {
}
} catch (OAuthErrorException e) {
event.event(EventType.LOGOUT);
event.detail(Details.REASON, e.getDescription());
event.error(Errors.INVALID_TOKEN);
return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.SESSION_NOT_ACTIVE);
}
Expand Down Expand Up @@ -538,9 +539,11 @@ private Response logoutToken() {
} catch (OAuthErrorException e) {
// KEYCLOAK-6771 Certificate Bound Token
if (MtlsHoKTokenUtil.CERT_VERIFY_ERROR_DESC.equals(e.getDescription())) {
event.detail(Details.REASON, e.getDescription());
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, e.getError(), e.getDescription(), Response.Status.UNAUTHORIZED);
} else {
event.detail(Details.REASON, e.getDescription());
event.error(Errors.INVALID_TOKEN);
throw new CorsErrorResponseException(cors, e.getError(), e.getDescription(), Response.Status.BAD_REQUEST);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ private void checkToken() {
String encodedToken = formParams.getFirst(PARAM_TOKEN);

if (encodedToken == null) {
event.detail(Details.REASON, "Token not provided");
event.error(Errors.INVALID_REQUEST);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "Token not provided",
Response.Status.BAD_REQUEST);
Expand All @@ -184,6 +185,7 @@ private void checkToken() {
}

if (!(TokenUtil.TOKEN_TYPE_REFRESH.equals(token.getType()) || TokenUtil.TOKEN_TYPE_OFFLINE.equals(token.getType()) || TokenUtil.TOKEN_TYPE_BEARER.equals(token.getType())|| TokenUtil.TOKEN_TYPE_DPOP.equals(token.getType()))) {
event.detail(Details.REASON, "Unsupported token type");
event.error(Errors.INVALID_TOKEN_TYPE);
throw new CorsErrorResponseException(cors, OAuthErrorException.UNSUPPORTED_TOKEN_TYPE, "Unsupported token type",
Response.Status.BAD_REQUEST);
Expand All @@ -193,11 +195,13 @@ private void checkToken() {
private void checkIssuedFor() {
String issuedFor = token.getIssuedFor();
if (issuedFor == null) {
event.detail(Details.REASON, "Issued for not set");
event.error(Errors.INVALID_TOKEN);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_TOKEN, "Invalid token", Response.Status.OK);
}

if (!client.getClientId().equals(issuedFor)) {
event.detail(Details.REASON, "Unmatching clients");
event.error(Errors.INVALID_REQUEST);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "Unmatching clients",
Response.Status.BAD_REQUEST);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException;
import org.keycloak.common.Profile;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.EventType;
import org.keycloak.models.AuthenticatedClientSessionModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.representations.AccessTokenResponse;
Expand Down Expand Up @@ -65,6 +65,7 @@ public Response process(Context context) {
session.clientPolicy().triggerOnEvent(new TokenRefreshContext(formParams));
refreshToken = formParams.getFirst(OAuth2Constants.REFRESH_TOKEN);
} catch (ClientPolicyException cpe) {
event.detail(Details.REASON, cpe.getErrorDetail());
event.error(cpe.getError());
throw new CorsErrorResponseException(cors, cpe.getError(), cpe.getErrorDetail(), cpe.getErrorStatus());
}
Expand All @@ -91,13 +92,16 @@ public Response process(Context context) {
logger.trace(e.getMessage(), e);
// KEYCLOAK-6771 Certificate Bound Token
if (MtlsHoKTokenUtil.CERT_VERIFY_ERROR_DESC.equals(e.getDescription())) {
event.detail(Details.REASON, e.getDescription());
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, e.getError(), e.getDescription(), Response.Status.UNAUTHORIZED);
} else {
event.detail(Details.REASON, e.getDescription());
event.error(Errors.INVALID_TOKEN);
throw new CorsErrorResponseException(cors, e.getError(), e.getDescription(), Response.Status.BAD_REQUEST);
}
} catch (ClientPolicyException cpe) {
event.detail(Details.REASON, cpe.getErrorDetail());
event.error(cpe.getError());
throw new CorsErrorResponseException(cors, cpe.getError(), cpe.getErrorDetail(), cpe.getErrorStatus());
}
Expand Down

0 comments on commit 261b689

Please sign in to comment.