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

98 lines
3.8 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 D4ScienceContextMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper {
private static final Logger logger = Logger.getLogger(D4ScienceContextMapper.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 D4Science Context Mapper";
private static final String PROVIDER_ID = "oidc-d4scince-context-mapper";
public static final String HEADER_NAME = "X-D4Science-Context";
// public static final String HEADER_NAME = "X-Infrastructure-Context";
// public static final String HEADER_NAME = "X-Infra-Context";
static {
OIDCAttributeMapperHelper.addTokenClaimNameConfig(configProperties);
OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, D4ScienceContextMapper.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 "Maps the D4Science context audience by reading the '" + 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());
}
}
}
}
}