Skip to content

Instantly share code, notes, and snippets.

@thomasdarimont
Created May 19, 2020 10:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomasdarimont/1dfd8ea07e9b071e5b2a6c8869cd1bee to your computer and use it in GitHub Desktop.
Save thomasdarimont/1dfd8ea07e9b071e5b2a6c8869cd1bee to your computer and use it in GitHub Desktop.
Custom UserAttributeMapper that skips expensive Group Attribute resolving, which is not used by Acme Keycloak.
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.ProtocolMapperUtils;
import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
import org.keycloak.protocol.oidc.mappers.UserAttributeMapper;
import org.keycloak.representations.IDToken;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
 * Custom {@link UserAttributeMapper} that skips expensive Group Attribute resolving, which is not used by Acme Keycloak.
 * Note: This {@link AcmeUserAttributeMapper} overrides Keycloak's default {@link UserAttributeMapper} because we use the same provider ID.
 */
public class AcmeUserAttributeMapper extends UserAttributeMapper {
    @Override
    protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
        UserModel user = userSession.getUser();
        String attributeName = mappingModel.getConfig().get(ProtocolMapperUtils.USER_ATTRIBUTE);
        boolean aggregateAttrs = Boolean.parseBoolean(mappingModel.getConfig().get(ProtocolMapperUtils.AGGREGATE_ATTRS));
        Collection<String> attributeValue = resolveAttribute(user, attributeName, aggregateAttrs);
        if (attributeValue == null) {
            return;
        }
        OIDCAttributeMapperHelper.mapClaim(token, mappingModel, attributeValue);
    }
    /**
     * Taken from {@link org.keycloak.models.utils.KeycloakModelUtils#resolveAttribute(UserModel, String, boolean)} but without
     * resolving group attributes.
     * @param user
     * @param name
     * @param aggregateAttrs
     * @return
     */
    protected Collection<String> resolveAttribute(UserModel user, String name, boolean aggregateAttrs) {
        List<String> values = user.getAttribute(name);
        Set<String> aggrValues = new HashSet<>();
        if (!values.isEmpty()) {
            if (!aggregateAttrs) {
                return values;
            }
            aggrValues.addAll(values);
        }
        return aggrValues;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment