NPE in HardcodedUserSessionAttributeMapper on Token Exchange

Closes #11996

Signed-off-by: Douglas Palmer <dpalmer@redhat.com>
This commit is contained in:
Douglas Palmer 2023-11-23 07:35:54 -08:00 committed by Pedro Igor
parent 7e78d29f8d
commit 5ce41a462b
5 changed files with 24 additions and 14 deletions

View file

@ -18,6 +18,7 @@ package org.keycloak.broker.provider;
import org.keycloak.models.Constants;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.sessions.AuthenticationSessionModel;
import java.util.ArrayList;
@ -48,7 +49,6 @@ public class BrokeredIdentityContext {
private IdentityProviderModel idpConfig;
private IdentityProvider idp;
private Map<String, Object> contextData = new HashMap<>();
private Map<String, String> claims = new HashMap<>();
private AuthenticationSessionModel authenticationSession;
public BrokeredIdentityContext(String id) {
@ -162,12 +162,26 @@ public class BrokeredIdentityContext {
this.contextData = contextData;
}
public Map<String, String> getClaims() {
return claims;
private Map<String, String> getSessionNotes() {
HashMap<String, String> sessionNotes = (HashMap<String, String>) this.contextData.get(Constants.MAPPER_SESSION_NOTES);
if (sessionNotes == null) {
sessionNotes = new HashMap<>();
this.contextData.put(Constants.MAPPER_SESSION_NOTES, sessionNotes);
}
return sessionNotes;
}
public void setClaims(Map<String, String> claims) {
this.claims = claims;
public void setSessionNote(String key, String value) {
if(authenticationSession != null) {
authenticationSession.setUserSessionNote(key, value);
}
else {
getSessionNotes().put(key, value);
}
}
public void addSessionNotesToUserSession(UserSessionModel userSession) {
getSessionNotes().forEach((k, v) -> userSession.setNote(k, v));
}
// Set the attribute, which will be available on "Update profile" page and in authenticators

View file

@ -106,6 +106,8 @@ public final class Constants {
// Groups already assigned by a mapper when updating brokered users.
public static final String MAPPER_GRANTED_GROUPS = "MAPPER_GRANTED_GROUPS";
public static final String MAPPER_SESSION_NOTES = "MAPPER_SESSION_NOTES";
// Indication to admin-rest-endpoint that realm keys should be re-generated
public static final String GENERATE = "GENERATE";

View file

@ -127,12 +127,7 @@ public class ClaimToUserSessionNoteMapper extends AbstractClaimMapper {
: valueEquals(value, claimValue);
if (claimValuesMatch) {
if(context.getAuthenticationSession() != null) {
context.getAuthenticationSession().setUserSessionNote(claim.getKey(), claimValue);
}
else {
context.getClaims().put(claim.getKey(), claimValue);
}
context.setSessionNote(claim.getKey(), claimValue);
}
}
}

View file

@ -114,6 +114,6 @@ public class HardcodedUserSessionAttributeMapper extends AbstractIdentityProvide
private void setHardcodedUserSessionAttribute(IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
String attribute = mapperModel.getConfig().get(ATTRIBUTE);
String attributeValue = mapperModel.getConfig().get(ATTRIBUTE_VALUE);
context.getAuthenticationSession().setUserSessionNote(attribute, attributeValue);
context.setSessionNote(attribute, attributeValue);
}
}

View file

@ -86,7 +86,6 @@ import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import java.util.UUID;
/**
* Default token exchange implementation
@ -515,7 +514,7 @@ public class DefaultTokenExchangeProvider implements TokenExchangeProvider {
userSession.setNote(IdentityProvider.EXTERNAL_IDENTITY_PROVIDER, externalIdpModel.get().getAlias());
userSession.setNote(IdentityProvider.FEDERATED_ACCESS_TOKEN, subjectToken);
context.getClaims().forEach((k, v) -> userSession.setNote(k, v));
context.addSessionNotesToUserSession(userSession);
return exchangeClientToClient(user, userSession, null, false);
}