keycloak-d4science-spi-parent/protocol-mapper/src/main/java/org/gcube/keycloak/protocol/oidc/mapper/GCubeContextMapper.java

96 lines
3.6 KiB
Java

package org.gcube.keycloak.protocol.oidc.mapper;
import java.util.ArrayList;
import java.util.List;
import org.jboss.logging.Logger;
import org.keycloak.models.ClientSessionContext;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.oidc.mappers.AbstractOIDCProtocolMapper;
import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.IDToken;
public class GCubeContextMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper {
private static final Logger logger = Logger.getLogger(GCubeContextMapper.class);
private static final List<ProviderConfigProperty> configProperties = new ArrayList<>();
// Assuring that the mapper is executed as last
private static final int PRIORITY = Integer.MAX_VALUE;
private static final String DISPLAY_TYPE = "OIDC GCube Context Mapper";
private static final String PROVIDER_ID = "oidc-gcube-context-mapper";
public static final String HEADER_NAME = "X-GCube-Context";
static {
OIDCAttributeMapperHelper.addTokenClaimNameConfig(configProperties);
OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, GCubeContextMapper.class);
}
@Override
public String getDisplayCategory() {
return TOKEN_MAPPER_CATEGORY;
}
@Override
public int getPriority() {
return PRIORITY;
}
@Override
public String getDisplayType() {
return DISPLAY_TYPE;
}
@Override
public String getHelpText() {
return "Reads GCube context from " + HEADER_NAME + " header and sets it as the configured token claim";
}
@Override
public List<ProviderConfigProperty> getConfigProperties() {
return configProperties;
}
@Override
public String getId() {
return PROVIDER_ID;
}
@Override
protected void setClaim(final IDToken token,
final ProtocolMapperModel mappingModel,
final UserSessionModel userSession,
final KeycloakSession keycloakSession,
final ClientSessionContext clientSessionCtx) {
// Since only the OIDCAccessTokenMapper interface is implemented, we are almost sure that
// the token object is an AccessToken but adding a specific check anyway
if (token instanceof AccessToken) {
logger.debugf("Looking for the '%s' header", HEADER_NAME);
String requestedD4SContext = keycloakSession.getContext().getRequestHeaders().getHeaderString(HEADER_NAME);
if (requestedD4SContext != null && !"".equals(requestedD4SContext)) {
logger.debugf("Checking resource access for the requested context: %s", requestedD4SContext);
if (((AccessToken) token).getResourceAccess().containsKey(requestedD4SContext)) {
logger.debugf("Mapping it as the configured claim: %s",
mappingModel.getConfig().get(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME));
OIDCAttributeMapperHelper.mapClaim(token, mappingModel, requestedD4SContext);
} else {
logger.warnf("Requested context '%s' is not accessible to the client: %s", requestedD4SContext,
clientSessionCtx.getClientSession().getClient().getName());
}
}
}
}
}