Skip to content

Commit

Permalink
feat(jans-auth-server): end session - if id_token is expired but sign…
Browse files Browse the repository at this point in the history
…ature is correct, we should make attempt to look up session by "sid" claim #3231
  • Loading branch information
yuriyz committed Dec 9, 2022
1 parent 7388690 commit 5dfa61e
Showing 1 changed file with 34 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import io.jans.as.server.service.external.ExternalEndSessionService;
import io.jans.as.server.service.external.context.EndSessionContext;
import io.jans.as.server.util.ServerUtil;
import io.jans.as.server.util.TokenHashUtil;
import io.jans.model.security.Identity;
import io.jans.util.Pair;
import io.jans.util.StringHelper;
Expand Down Expand Up @@ -125,16 +126,16 @@ public Response requestEndSession(String idTokenHint, String postLogoutRedirectU
errorResponseFactory.validateFeatureEnabled(FeatureFlagType.END_SESSION);

final SessionId sidSession = validateSidRequestParameter(sid, postLogoutRedirectUri);
Jwt idToken = validateIdTokenHint(idTokenHint, sidSession, postLogoutRedirectUri);
Jwt validatedIdToken = validateIdTokenHint(idTokenHint, sidSession, postLogoutRedirectUri);

final Pair<SessionId, AuthorizationGrant> pair = getPair(idTokenHint, sid, httpRequest);
final Pair<SessionId, AuthorizationGrant> pair = getPair(idTokenHint, validatedIdToken, sid, httpRequest);
if (pair.getFirst() == null) {
final String reason = "Failed to identify session by session_id query parameter or by session_id cookie.";
throw new WebApplicationException(createErrorResponse(postLogoutRedirectUri, EndSessionErrorResponseType.INVALID_GRANT_AND_SESSION, reason));
}

postLogoutRedirectUri = validatePostLogoutRedirectUri(postLogoutRedirectUri, pair);
validateSid(postLogoutRedirectUri, idToken, pair.getFirst());
validateSid(postLogoutRedirectUri, validatedIdToken, pair.getFirst());

endSession(pair, httpRequest, httpResponse);
auditLogging(httpRequest, pair);
Expand Down Expand Up @@ -331,6 +332,7 @@ protected Jwt validateIdTokenHint(String idTokenHint, SessionId sidSession, Stri

if (tokenHintGrant == null && isRejectEndSessionIfIdTokenExpired) {
final String reason = "id_token_hint is not valid. Logout is rejected. id_token_hint can be skipped or otherwise valid value must be provided.";
log.trace(reason);
throw new WebApplicationException(createErrorResponse(postLogoutRedirectUri, EndSessionErrorResponseType.INVALID_GRANT_AND_SESSION, reason));
}
return validateIdTokenJwt(tokenHintGrant, idTokenHint, sidSession, postLogoutRedirectUri);
Expand All @@ -342,9 +344,11 @@ private Jwt validateIdTokenJwt(AuthorizationGrant tokenHintGrant, String idToken
try {
final Jwt jwt = Jwt.parse(idTokenHint);
if (tokenHintGrant != null) { // id_token is in db
log.debug("Found id_token in db.");
return jwt;
}
validateIdTokenSignature(sidSession, jwt, postLogoutRedirectUri);
log.debug("id_token is validated successfully.");
return jwt;
} catch (InvalidJwtException e) {
log.error("Unable to parse id_token_hint as JWT.", e);
Expand Down Expand Up @@ -381,7 +385,12 @@ protected AuthorizationGrant getTokenHintGrant(String idTokenHint) {
return null;
}

AuthorizationGrant authorizationGrant = authorizationGrantList.getAuthorizationGrantByIdToken(idTokenHint);
AuthorizationGrant authorizationGrant = authorizationGrantList.getAuthorizationGrantByIdToken(TokenHashUtil.hash(idTokenHint));
if (authorizationGrant != null) {
return authorizationGrant;
}

authorizationGrant = authorizationGrantList.getAuthorizationGrantByIdToken(idTokenHint);
if (authorizationGrant != null) {
return authorizationGrant;
}
Expand Down Expand Up @@ -457,7 +466,7 @@ private Response okResponse(String html) {
build();
}

private Pair<SessionId, AuthorizationGrant> getPair(String idTokenHint, String sid, HttpServletRequest httpRequest) {
private Pair<SessionId, AuthorizationGrant> getPair(String idTokenHint, Jwt validatedIdToken, String sid, HttpServletRequest httpRequest) {
AuthorizationGrant authorizationGrant = authorizationGrantList.getAuthorizationGrantByIdToken(idTokenHint);
if (authorizationGrant == null) {
Boolean endSessionWithAccessToken = appConfiguration.getEndSessionWithAccessToken();
Expand All @@ -466,20 +475,32 @@ private Pair<SessionId, AuthorizationGrant> getPair(String idTokenHint, String s
}
}

SessionId ldapSessionId = null;
SessionId sessionId = null;

try {
String id = cookieService.getSessionIdFromCookie(httpRequest);
if (StringHelper.isNotEmpty(id)) {
ldapSessionId = sessionIdService.getSessionId(id);
String cookieSessionId = cookieService.getSessionIdFromCookie(httpRequest);
if (StringHelper.isNotEmpty(cookieSessionId)) {
sessionId = sessionIdService.getSessionId(cookieSessionId);
}
if (StringUtils.isNotBlank(sid) && ldapSessionId == null) {
ldapSessionId = sessionIdService.getSessionBySid(sid);
if (sessionId == null && StringUtils.isNotBlank(sid)) {
sessionId = sessionIdService.getSessionBySid(sid);
}
if (sessionId == null && validatedIdToken != null) {
final String sidClaim = validatedIdToken.getClaims().getClaimAsString("sid");
if (StringUtils.isNotBlank(sidClaim)) {
sessionId = sessionIdService.getSessionBySid(sidClaim);
}
}

if (sessionId == null) {
log.trace("Unable to find session for ending.");
} else {
log.trace("Found session for ending successfully.");
}
} catch (Exception e) {
log.error("Failed to current session id.", e);
log.error("Failed to find current session id.", e);
}
return new Pair<>(ldapSessionId, authorizationGrant);
return new Pair<>(sessionId, authorizationGrant);
}

private void endSession(Pair<SessionId, AuthorizationGrant> pair, HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
Expand Down

0 comments on commit 5dfa61e

Please sign in to comment.