mirror of https://github.com/jacekkow/keycloak-protocol-cas

Matthias Piepkorn
2018-06-17 b8d686069c3249e4bd11eb5eef95f5bd51ea58fb
update for KEYCLOAK-6630 Client scopes initial support
11 files modified
121 ■■■■■ changed files
src/main/java/org/keycloak/protocol/cas/CASLoginProtocol.java 3 ●●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/CASLoginProtocolFactory.java 57 ●●●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/endpoints/ServiceValidateEndpoint.java 10 ●●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/mappers/CASAttributeMapperHelper.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/mappers/FullNameMapper.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/mappers/GroupMembershipMapper.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/mappers/UserAttributeMapper.java 4 ●●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/mappers/UserClientRoleMappingMapper.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/mappers/UserPropertyMapper.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/mappers/UserRealmRoleMappingMapper.java 2 ●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/mappers/UserSessionNoteMapper.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/org/keycloak/protocol/cas/CASLoginProtocol.java
@@ -85,7 +85,8 @@
    }
    @Override
    public Response authenticated(UserSessionModel userSession, AuthenticatedClientSessionModel clientSession) {
    public Response authenticated(UserSessionModel userSession, ClientSessionContext clientSessionCtx) {
        AuthenticatedClientSessionModel clientSession = clientSessionCtx.getClientSession();
        ClientSessionCode<AuthenticatedClientSessionModel> accessCode = new ClientSessionCode<>(session, realm, clientSession);
        String service = clientSession.getRedirectUri();
src/main/java/org/keycloak/protocol/cas/CASLoginProtocolFactory.java
@@ -2,23 +2,21 @@
import org.jboss.logging.Logger;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.*;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.protocol.AbstractLoginProtocolFactory;
import org.keycloak.protocol.LoginProtocol;
import org.keycloak.protocol.ProtocolMapperUtils;
import org.keycloak.protocol.cas.mappers.FullNameMapper;
import org.keycloak.protocol.cas.mappers.UserAttributeMapper;
import org.keycloak.protocol.cas.mappers.UserPropertyMapper;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.ClientTemplateRepresentation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.JSON_TYPE;
import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME;
public class CASLoginProtocolFactory extends AbstractLoginProtocolFactory {
    private static final Logger logger = Logger.getLogger(CASLoginProtocolFactory.class);
@@ -43,49 +41,43 @@
    }
    @Override
    public List<ProtocolMapperModel> getBuiltinMappers() {
    public Map<String, ProtocolMapperModel> getBuiltinMappers() {
        return builtins;
    }
    @Override
    public List<ProtocolMapperModel> getDefaultBuiltinMappers() {
        return defaultBuiltins;
    }
    static List<ProtocolMapperModel> builtins = new ArrayList<>();
    static Map<String, ProtocolMapperModel> builtins = new HashMap<>();
    static List<ProtocolMapperModel> defaultBuiltins = new ArrayList<>();
    static {
        ProtocolMapperModel model;
        model = UserPropertyMapper.create(EMAIL, "email", "mail", "String",
                true, EMAIL_CONSENT_TEXT);
        builtins.add(model);
        model = UserPropertyMapper.create(EMAIL, "email", "mail", "String");
        builtins.put(EMAIL, model);
        defaultBuiltins.add(model);
        model = UserPropertyMapper.create(GIVEN_NAME, "firstName", "givenName", "String",
                true, GIVEN_NAME_CONSENT_TEXT);
        builtins.add(model);
        model = UserPropertyMapper.create(GIVEN_NAME, "firstName", "givenName", "String");
        builtins.put(GIVEN_NAME, model);
        defaultBuiltins.add(model);
        model = UserPropertyMapper.create(FAMILY_NAME, "lastName", "sn", "String",
                true, FAMILY_NAME_CONSENT_TEXT);
        builtins.add(model);
        model = UserPropertyMapper.create(FAMILY_NAME, "lastName", "sn", "String");
        builtins.put(FAMILY_NAME, model);
        defaultBuiltins.add(model);
        model = UserPropertyMapper.create(EMAIL_VERIFIED,
                "emailVerified",
                "emailVerified", "boolean",
                false, EMAIL_VERIFIED_CONSENT_TEXT);
        builtins.add(model);
                "emailVerified", "boolean");
        builtins.put(EMAIL_VERIFIED, model);
        model = UserAttributeMapper.create(LOCALE,
                "locale",
                "locale", "String",
                false, LOCALE_CONSENT_TEXT,
                false);
        builtins.add(model);
        builtins.put(LOCALE, model);
        model = FullNameMapper.create(FULL_NAME, "cn",
                true, FULL_NAME_CONSENT_TEXT);
        builtins.add(model);
        model = FullNameMapper.create(FULL_NAME, "cn");
        builtins.put(FULL_NAME, model);
        defaultBuiltins.add(model);
    }
    @Override
    protected void createDefaultClientScopesImpl(RealmModel newRealm) {
        // no-op
    }
    @Override
@@ -115,10 +107,5 @@
        if (rep.getAdminUrl() == null && rep.getRootUrl() != null) {
            newClient.setManagementUrl(rep.getRootUrl());
        }
    }
    @Override
    public void setupTemplateDefaults(ClientTemplateRepresentation clientRep, ClientTemplateModel newClient) {
    }
}
src/main/java/org/keycloak/protocol/cas/endpoints/ServiceValidateEndpoint.java
@@ -1,10 +1,7 @@
package org.keycloak.protocol.cas.endpoints;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.*;
import org.keycloak.protocol.ProtocolMapper;
import org.keycloak.protocol.cas.mappers.CASAttributeMapper;
import org.keycloak.protocol.cas.representations.CASServiceResponse;
@@ -12,6 +9,7 @@
import org.keycloak.protocol.cas.utils.ContentTypeHelper;
import org.keycloak.protocol.cas.utils.ServiceResponseHelper;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.util.DefaultClientSessionContext;
import javax.ws.rs.core.*;
import java.util.HashMap;
@@ -29,8 +27,10 @@
    @Override
    protected Response successResponse() {
        UserSessionModel userSession = clientSession.getUserSession();
        // CAS protocol does not support scopes, so pass null scopeParam
        ClientSessionContext clientSessionCtx = DefaultClientSessionContext.fromClientSessionAndScopeParameter(clientSession, null);
        Set<ProtocolMapperModel> mappings = new ClientSessionCode<>(session, realm, clientSession).getRequestedProtocolMappers();
        Set<ProtocolMapperModel> mappings = clientSessionCtx.getProtocolMappers();
        KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
        Map<String, Object> attributes = new HashMap<>();
        for (ProtocolMapperModel mapping : mappings) {
src/main/java/org/keycloak/protocol/cas/mappers/CASAttributeMapperHelper.java
@@ -10,14 +10,11 @@
public class CASAttributeMapperHelper {
    public static ProtocolMapperModel createClaimMapper(String name,
                                                        String tokenClaimName, String claimType,
                                                        boolean consentRequired, String consentText,
                                                        String mapperId) {
        ProtocolMapperModel mapper = new ProtocolMapperModel();
        mapper.setName(name);
        mapper.setProtocolMapper(mapperId);
        mapper.setProtocol(CASLoginProtocol.LOGIN_PROTOCOL);
        mapper.setConsentRequired(consentRequired);
        mapper.setConsentText(consentText);
        Map<String, String> config = new HashMap<String, String>();
        config.put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, tokenClaimName);
        config.put(OIDCAttributeMapperHelper.JSON_TYPE, claimType);
src/main/java/org/keycloak/protocol/cas/mappers/FullNameMapper.java
@@ -48,9 +48,8 @@
        setMappedAttribute(attributes, mappingModel, first + last);
    }
    public static ProtocolMapperModel create(String name, String tokenClaimName,
                                             boolean consentRequired, String consentText) {
    public static ProtocolMapperModel create(String name, String tokenClaimName) {
        return CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
                "String", consentRequired, consentText, PROVIDER_ID);
                "String", PROVIDER_ID);
    }
}
src/main/java/org/keycloak/protocol/cas/mappers/GroupMembershipMapper.java
@@ -69,10 +69,9 @@
        return "true".equals(mappingModel.getConfig().get(FULL_PATH));
    }
    public static ProtocolMapperModel create(String name, String tokenClaimName,
                                             boolean consentRequired, String consentText, boolean fullPath) {
    public static ProtocolMapperModel create(String name, String tokenClaimName, boolean fullPath) {
        ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
                "String", consentRequired, consentText, PROVIDER_ID);
                "String", PROVIDER_ID);
        mapper.getConfig().put(FULL_PATH, Boolean.toString(fullPath));
        return mapper;
    }
src/main/java/org/keycloak/protocol/cas/mappers/UserAttributeMapper.java
@@ -68,9 +68,9 @@
    public static ProtocolMapperModel create(String name, String userAttribute,
                                             String tokenClaimName, String claimType,
                                             boolean consentRequired, String consentText, boolean multivalued) {
                                             boolean multivalued) {
        ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
                claimType, consentRequired, consentText, PROVIDER_ID);
                claimType, PROVIDER_ID);
        mapper.getConfig().put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute);
        if (multivalued) {
            mapper.getConfig().put(ProtocolMapperUtils.MULTIVALUED, "true");
src/main/java/org/keycloak/protocol/cas/mappers/UserClientRoleMappingMapper.java
@@ -2,6 +2,7 @@
import org.keycloak.models.*;
import org.keycloak.protocol.ProtocolMapperUtils;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
import org.keycloak.provider.ProviderConfigProperty;
@@ -78,10 +79,7 @@
            return RoleModel::isClientRole;
        }
        ClientTemplateModel template = client.getClientTemplate();
        boolean useTemplateScope = template != null && client.useTemplateScope();
        boolean fullScopeAllowed = (useTemplateScope && template.isFullScopeAllowed()) || client.isFullScopeAllowed();
        boolean fullScopeAllowed = client.isFullScopeAllowed();
        Set<RoleModel> clientRoleMappings = client.getRoles();
        if (fullScopeAllowed) {
            return clientRoleMappings::contains;
@@ -89,16 +87,10 @@
        Set<RoleModel> scopeMappings = new HashSet<>();
        if (useTemplateScope) {
            Set<RoleModel> templateScopeMappings = template.getScopeMappings();
            if (templateScopeMappings != null) {
                scopeMappings.addAll(templateScopeMappings);
            }
        }
        Set<RoleModel> clientScopeMappings = client.getScopeMappings();
        if (clientScopeMappings != null) {
            scopeMappings.addAll(clientScopeMappings);
        // CAS protocol does not support scopes, so pass null scopeParam
        Set<ClientScopeModel> clientScopes = TokenManager.getRequestedClientScopes(null, client);
        for (ClientScopeModel clientScope : clientScopes) {
            scopeMappings.addAll(clientScope.getScopeMappings());
        }
        return role -> clientRoleMappings.contains(role) && scopeMappings.contains(role);
@@ -107,7 +99,7 @@
    public static ProtocolMapperModel create(String clientId, String clientRolePrefix,
                                             String name, String tokenClaimName) {
        ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
                "String", true, name, PROVIDER_ID);
                "String", PROVIDER_ID);
        mapper.getConfig().put(ProtocolMapperUtils.USER_MODEL_CLIENT_ROLE_MAPPING_CLIENT_ID, clientId);
        mapper.getConfig().put(ProtocolMapperUtils.USER_MODEL_CLIENT_ROLE_MAPPING_ROLE_PREFIX, clientRolePrefix);
        return mapper;
src/main/java/org/keycloak/protocol/cas/mappers/UserPropertyMapper.java
@@ -58,10 +58,9 @@
    }
    public static ProtocolMapperModel create(String name, String userAttribute,
                                             String tokenClaimName, String claimType,
                                             boolean consentRequired, String consentText) {
                                             String tokenClaimName, String claimType) {
        ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
                claimType, consentRequired, consentText, PROVIDER_ID);
                claimType, PROVIDER_ID);
        mapper.getConfig().put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute);
        return mapper;
    }
src/main/java/org/keycloak/protocol/cas/mappers/UserRealmRoleMappingMapper.java
@@ -60,7 +60,7 @@
    public static ProtocolMapperModel create(String realmRolePrefix, String name, String tokenClaimName) {
        ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
                "String", true, name, PROVIDER_ID);
                "String", PROVIDER_ID);
        mapper.getConfig().put(ProtocolMapperUtils.USER_MODEL_REALM_ROLE_MAPPING_ROLE_PREFIX, realmRolePrefix);
        return mapper;
    }
src/main/java/org/keycloak/protocol/cas/mappers/UserSessionNoteMapper.java
@@ -63,10 +63,9 @@
    public static ProtocolMapperModel create(String name,
                                             String userSessionNote,
                                             String tokenClaimName, String jsonType,
                                             boolean consentRequired, String consentText) {
                                             String tokenClaimName, String jsonType) {
        ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
                jsonType, consentRequired, consentText, PROVIDER_ID);
                jsonType, PROVIDER_ID);
        mapper.getConfig().put(ProtocolMapperUtils.USER_SESSION_NOTE, userSessionNote);
        return mapper;
    }