Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -713,8 +713,21 @@ protected <T extends AbstractExternalOAuthIdentityProviderDefinition<T>> Map<Str
Jwt decodeIdToken = jwtToken.getJwt();
log.debug("Deserializing id_token claims");

return JsonUtils.readValue(decodeIdToken.getClaims(), new TypeReference<>() {
Map<String, Object> claims = JsonUtils.readValue(decodeIdToken.getClaims(), new TypeReference<>() {
});

if (config instanceof OIDCIdentityProviderDefinition) {
String expectedNonce = getSessionValue(SessionUtils.nonceParameterAttributeKeyForIdp(identityProvider.getOriginKey()));
if (StringUtils.hasText(expectedNonce)) {
String tokenNonce = (String) claims.get("nonce");
if (!expectedNonce.equals(tokenNonce)) {
throw new InvalidTokenException("ID token nonce does not match session nonce");
}
clearSessionValue(SessionUtils.nonceParameterAttributeKeyForIdp(identityProvider.getOriginKey()));
}
}
Comment on lines +719 to +728

return claims;
}
}

Expand Down Expand Up @@ -879,6 +892,18 @@ private String getSessionValue(String value) {
}
}

private void clearSessionValue(String value) {
try {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
jakarta.servlet.http.HttpSession session = attr.getRequest().getSession(false);
if (session != null) {
session.removeAttribute(value);
}
} catch (Exception e) {
log.warn("Exception", e);
}
}

private String getClientAuthHeader(AbstractExternalOAuthIdentityProviderDefinition config) {
String clientAuth = new String(Base64.encodeBase64((config.getRelyingPartyId() + ":" + config.getRelyingPartySecret()).getBytes()));
return "Basic " + clientAuth;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ public String getIdpAuthenticationUrl(

if (OIDCIdentityProviderDefinition.class.equals(definition.getParameterizedClass())) {
var nonceGenerator = new RandomValueStringGenerator(22);
uriBuilder.queryParam("nonce", nonceGenerator.generate());
String nonce = nonceGenerator.generate();
SessionUtils.setStateParam(request.getSession(), SessionUtils.nonceParameterAttributeKeyForIdp(idpOriginKey), nonce);
uriBuilder.queryParam("nonce", nonce);
Comment on lines 121 to +125

Map<String, String> additionalParameters = ofNullable(((OIDCIdentityProviderDefinition) definition).getAdditionalAuthzParameters()).orElse(emptyMap());
additionalParameters.keySet().forEach(e -> uriBuilder.queryParam(e, additionalParameters.get(e)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public final class SessionUtils {
private static final String EXTERNAL_OAUTH_REDIRECT_URI_ATTRIBUTE_PREFIX = "external-oauth-redirect-uri-";
private static final String EXTERNAL_OAUTH_SUPERSEDED_STATE_ATTRIBUTE_PREFIX = "external-oauth-superseded-state-";

private static final String EXTERNAL_OAUTH_NONCE_ATTRIBUTE_PREFIX = "external-oauth-nonce-";

/**
* Upper bound on how many recently-superseded state values we remember per IDP origin.
* Keeps the session footprint bounded while still tolerating a handful of concurrent tabs.
Expand Down Expand Up @@ -156,4 +158,8 @@ public static String redirectUriParameterAttributeKeyForIdp(String idpOriginKey)
public static String supersededStateParameterAttributeKeyForIdp(String idpOriginKey) {
return EXTERNAL_OAUTH_SUPERSEDED_STATE_ATTRIBUTE_PREFIX + idpOriginKey;
}

public static String nonceParameterAttributeKeyForIdp(String idpOriginKey) {
return EXTERNAL_OAUTH_NONCE_ATTRIBUTE_PREFIX + idpOriginKey;
}
}
Loading