Commit b8d68606 authored by Matthias Piepkorn's avatar Matthias Piepkorn
Browse files

update for KEYCLOAK-6630 Client scopes initial support

parent 2dc9e536
...@@ -85,7 +85,8 @@ public class CASLoginProtocol implements LoginProtocol { ...@@ -85,7 +85,8 @@ public class CASLoginProtocol implements LoginProtocol {
} }
@Override @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); ClientSessionCode<AuthenticatedClientSessionModel> accessCode = new ClientSessionCode<>(session, realm, clientSession);
String service = clientSession.getRedirectUri(); String service = clientSession.getRedirectUri();
......
...@@ -2,24 +2,22 @@ package org.keycloak.protocol.cas; ...@@ -2,24 +2,22 @@ package org.keycloak.protocol.cas;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.events.EventBuilder; 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.AbstractLoginProtocolFactory;
import org.keycloak.protocol.LoginProtocol; import org.keycloak.protocol.LoginProtocol;
import org.keycloak.protocol.ProtocolMapperUtils;
import org.keycloak.protocol.cas.mappers.FullNameMapper; import org.keycloak.protocol.cas.mappers.FullNameMapper;
import org.keycloak.protocol.cas.mappers.UserAttributeMapper; import org.keycloak.protocol.cas.mappers.UserAttributeMapper;
import org.keycloak.protocol.cas.mappers.UserPropertyMapper; import org.keycloak.protocol.cas.mappers.UserPropertyMapper;
import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.ClientTemplateRepresentation;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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 { public class CASLoginProtocolFactory extends AbstractLoginProtocolFactory {
private static final Logger logger = Logger.getLogger(CASLoginProtocolFactory.class); private static final Logger logger = Logger.getLogger(CASLoginProtocolFactory.class);
...@@ -43,51 +41,45 @@ public class CASLoginProtocolFactory extends AbstractLoginProtocolFactory { ...@@ -43,51 +41,45 @@ public class CASLoginProtocolFactory extends AbstractLoginProtocolFactory {
} }
@Override @Override
public List<ProtocolMapperModel> getBuiltinMappers() { public Map<String, ProtocolMapperModel> getBuiltinMappers() {
return builtins; return builtins;
} }
@Override static Map<String, ProtocolMapperModel> builtins = new HashMap<>();
public List<ProtocolMapperModel> getDefaultBuiltinMappers() {
return defaultBuiltins;
}
static List<ProtocolMapperModel> builtins = new ArrayList<>();
static List<ProtocolMapperModel> defaultBuiltins = new ArrayList<>(); static List<ProtocolMapperModel> defaultBuiltins = new ArrayList<>();
static { static {
ProtocolMapperModel model; ProtocolMapperModel model;
model = UserPropertyMapper.create(EMAIL, "email", "mail", "String", model = UserPropertyMapper.create(EMAIL, "email", "mail", "String");
true, EMAIL_CONSENT_TEXT); builtins.put(EMAIL, model);
builtins.add(model);
defaultBuiltins.add(model); defaultBuiltins.add(model);
model = UserPropertyMapper.create(GIVEN_NAME, "firstName", "givenName", "String", model = UserPropertyMapper.create(GIVEN_NAME, "firstName", "givenName", "String");
true, GIVEN_NAME_CONSENT_TEXT); builtins.put(GIVEN_NAME, model);
builtins.add(model);
defaultBuiltins.add(model); defaultBuiltins.add(model);
model = UserPropertyMapper.create(FAMILY_NAME, "lastName", "sn", "String", model = UserPropertyMapper.create(FAMILY_NAME, "lastName", "sn", "String");
true, FAMILY_NAME_CONSENT_TEXT); builtins.put(FAMILY_NAME, model);
builtins.add(model);
defaultBuiltins.add(model); defaultBuiltins.add(model);
model = UserPropertyMapper.create(EMAIL_VERIFIED, model = UserPropertyMapper.create(EMAIL_VERIFIED,
"emailVerified", "emailVerified",
"emailVerified", "boolean", "emailVerified", "boolean");
false, EMAIL_VERIFIED_CONSENT_TEXT); builtins.put(EMAIL_VERIFIED, model);
builtins.add(model);
model = UserAttributeMapper.create(LOCALE, model = UserAttributeMapper.create(LOCALE,
"locale", "locale",
"locale", "String", "locale", "String",
false, LOCALE_CONSENT_TEXT,
false); false);
builtins.add(model); builtins.put(LOCALE, model);
model = FullNameMapper.create(FULL_NAME, "cn", model = FullNameMapper.create(FULL_NAME, "cn");
true, FULL_NAME_CONSENT_TEXT); builtins.put(FULL_NAME, model);
builtins.add(model);
defaultBuiltins.add(model); defaultBuiltins.add(model);
} }
@Override
protected void createDefaultClientScopesImpl(RealmModel newRealm) {
// no-op
}
@Override @Override
protected void addDefaults(ClientModel client) { protected void addDefaults(ClientModel client) {
for (ProtocolMapperModel model : defaultBuiltins) client.addProtocolMapper(model); for (ProtocolMapperModel model : defaultBuiltins) client.addProtocolMapper(model);
...@@ -116,9 +108,4 @@ public class CASLoginProtocolFactory extends AbstractLoginProtocolFactory { ...@@ -116,9 +108,4 @@ public class CASLoginProtocolFactory extends AbstractLoginProtocolFactory {
newClient.setManagementUrl(rep.getRootUrl()); newClient.setManagementUrl(rep.getRootUrl());
} }
} }
@Override
public void setupTemplateDefaults(ClientTemplateRepresentation clientRep, ClientTemplateModel newClient) {
}
} }
package org.keycloak.protocol.cas.endpoints; package org.keycloak.protocol.cas.endpoints;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.*;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.ProtocolMapper; import org.keycloak.protocol.ProtocolMapper;
import org.keycloak.protocol.cas.mappers.CASAttributeMapper; import org.keycloak.protocol.cas.mappers.CASAttributeMapper;
import org.keycloak.protocol.cas.representations.CASServiceResponse; import org.keycloak.protocol.cas.representations.CASServiceResponse;
...@@ -12,6 +9,7 @@ import org.keycloak.protocol.cas.utils.CASValidationException; ...@@ -12,6 +9,7 @@ import org.keycloak.protocol.cas.utils.CASValidationException;
import org.keycloak.protocol.cas.utils.ContentTypeHelper; import org.keycloak.protocol.cas.utils.ContentTypeHelper;
import org.keycloak.protocol.cas.utils.ServiceResponseHelper; import org.keycloak.protocol.cas.utils.ServiceResponseHelper;
import org.keycloak.services.managers.ClientSessionCode; import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.util.DefaultClientSessionContext;
import javax.ws.rs.core.*; import javax.ws.rs.core.*;
import java.util.HashMap; import java.util.HashMap;
...@@ -29,8 +27,10 @@ public class ServiceValidateEndpoint extends ValidateEndpoint { ...@@ -29,8 +27,10 @@ public class ServiceValidateEndpoint extends ValidateEndpoint {
@Override @Override
protected Response successResponse() { protected Response successResponse() {
UserSessionModel userSession = clientSession.getUserSession(); 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(); KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
Map<String, Object> attributes = new HashMap<>(); Map<String, Object> attributes = new HashMap<>();
for (ProtocolMapperModel mapping : mappings) { for (ProtocolMapperModel mapping : mappings) {
......
...@@ -10,14 +10,11 @@ import java.util.Map; ...@@ -10,14 +10,11 @@ import java.util.Map;
public class CASAttributeMapperHelper { public class CASAttributeMapperHelper {
public static ProtocolMapperModel createClaimMapper(String name, public static ProtocolMapperModel createClaimMapper(String name,
String tokenClaimName, String claimType, String tokenClaimName, String claimType,
boolean consentRequired, String consentText,
String mapperId) { String mapperId) {
ProtocolMapperModel mapper = new ProtocolMapperModel(); ProtocolMapperModel mapper = new ProtocolMapperModel();
mapper.setName(name); mapper.setName(name);
mapper.setProtocolMapper(mapperId); mapper.setProtocolMapper(mapperId);
mapper.setProtocol(CASLoginProtocol.LOGIN_PROTOCOL); mapper.setProtocol(CASLoginProtocol.LOGIN_PROTOCOL);
mapper.setConsentRequired(consentRequired);
mapper.setConsentText(consentText);
Map<String, String> config = new HashMap<String, String>(); Map<String, String> config = new HashMap<String, String>();
config.put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, tokenClaimName); config.put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, tokenClaimName);
config.put(OIDCAttributeMapperHelper.JSON_TYPE, claimType); config.put(OIDCAttributeMapperHelper.JSON_TYPE, claimType);
......
...@@ -48,9 +48,8 @@ public class FullNameMapper extends AbstractCASProtocolMapper { ...@@ -48,9 +48,8 @@ public class FullNameMapper extends AbstractCASProtocolMapper {
setMappedAttribute(attributes, mappingModel, first + last); setMappedAttribute(attributes, mappingModel, first + last);
} }
public static ProtocolMapperModel create(String name, String tokenClaimName, public static ProtocolMapperModel create(String name, String tokenClaimName) {
boolean consentRequired, String consentText) {
return CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName, return CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
"String", consentRequired, consentText, PROVIDER_ID); "String", PROVIDER_ID);
} }
} }
...@@ -69,10 +69,9 @@ public class GroupMembershipMapper extends AbstractCASProtocolMapper { ...@@ -69,10 +69,9 @@ public class GroupMembershipMapper extends AbstractCASProtocolMapper {
return "true".equals(mappingModel.getConfig().get(FULL_PATH)); return "true".equals(mappingModel.getConfig().get(FULL_PATH));
} }
public static ProtocolMapperModel create(String name, String tokenClaimName, public static ProtocolMapperModel create(String name, String tokenClaimName, boolean fullPath) {
boolean consentRequired, String consentText, boolean fullPath) {
ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName, ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
"String", consentRequired, consentText, PROVIDER_ID); "String", PROVIDER_ID);
mapper.getConfig().put(FULL_PATH, Boolean.toString(fullPath)); mapper.getConfig().put(FULL_PATH, Boolean.toString(fullPath));
return mapper; return mapper;
} }
......
...@@ -68,9 +68,9 @@ public class UserAttributeMapper extends AbstractCASProtocolMapper { ...@@ -68,9 +68,9 @@ public class UserAttributeMapper extends AbstractCASProtocolMapper {
public static ProtocolMapperModel create(String name, String userAttribute, public static ProtocolMapperModel create(String name, String userAttribute,
String tokenClaimName, String claimType, String tokenClaimName, String claimType,
boolean consentRequired, String consentText, boolean multivalued) { boolean multivalued) {
ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName, ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
claimType, consentRequired, consentText, PROVIDER_ID); claimType, PROVIDER_ID);
mapper.getConfig().put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute); mapper.getConfig().put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute);
if (multivalued) { if (multivalued) {
mapper.getConfig().put(ProtocolMapperUtils.MULTIVALUED, "true"); mapper.getConfig().put(ProtocolMapperUtils.MULTIVALUED, "true");
......
...@@ -2,6 +2,7 @@ package org.keycloak.protocol.cas.mappers; ...@@ -2,6 +2,7 @@ package org.keycloak.protocol.cas.mappers;
import org.keycloak.models.*; import org.keycloak.models.*;
import org.keycloak.protocol.ProtocolMapperUtils; import org.keycloak.protocol.ProtocolMapperUtils;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigProperty;
...@@ -78,10 +79,7 @@ public class UserClientRoleMappingMapper extends AbstractUserRoleMappingMapper { ...@@ -78,10 +79,7 @@ public class UserClientRoleMappingMapper extends AbstractUserRoleMappingMapper {
return RoleModel::isClientRole; return RoleModel::isClientRole;
} }
ClientTemplateModel template = client.getClientTemplate(); boolean fullScopeAllowed = client.isFullScopeAllowed();
boolean useTemplateScope = template != null && client.useTemplateScope();
boolean fullScopeAllowed = (useTemplateScope && template.isFullScopeAllowed()) || client.isFullScopeAllowed();
Set<RoleModel> clientRoleMappings = client.getRoles(); Set<RoleModel> clientRoleMappings = client.getRoles();
if (fullScopeAllowed) { if (fullScopeAllowed) {
return clientRoleMappings::contains; return clientRoleMappings::contains;
...@@ -89,16 +87,10 @@ public class UserClientRoleMappingMapper extends AbstractUserRoleMappingMapper { ...@@ -89,16 +87,10 @@ public class UserClientRoleMappingMapper extends AbstractUserRoleMappingMapper {
Set<RoleModel> scopeMappings = new HashSet<>(); Set<RoleModel> scopeMappings = new HashSet<>();
if (useTemplateScope) { // CAS protocol does not support scopes, so pass null scopeParam
Set<RoleModel> templateScopeMappings = template.getScopeMappings(); Set<ClientScopeModel> clientScopes = TokenManager.getRequestedClientScopes(null, client);
if (templateScopeMappings != null) { for (ClientScopeModel clientScope : clientScopes) {
scopeMappings.addAll(templateScopeMappings); scopeMappings.addAll(clientScope.getScopeMappings());
}
}
Set<RoleModel> clientScopeMappings = client.getScopeMappings();
if (clientScopeMappings != null) {
scopeMappings.addAll(clientScopeMappings);
} }
return role -> clientRoleMappings.contains(role) && scopeMappings.contains(role); return role -> clientRoleMappings.contains(role) && scopeMappings.contains(role);
...@@ -107,7 +99,7 @@ public class UserClientRoleMappingMapper extends AbstractUserRoleMappingMapper { ...@@ -107,7 +99,7 @@ public class UserClientRoleMappingMapper extends AbstractUserRoleMappingMapper {
public static ProtocolMapperModel create(String clientId, String clientRolePrefix, public static ProtocolMapperModel create(String clientId, String clientRolePrefix,
String name, String tokenClaimName) { String name, String tokenClaimName) {
ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, 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_CLIENT_ID, clientId);
mapper.getConfig().put(ProtocolMapperUtils.USER_MODEL_CLIENT_ROLE_MAPPING_ROLE_PREFIX, clientRolePrefix); mapper.getConfig().put(ProtocolMapperUtils.USER_MODEL_CLIENT_ROLE_MAPPING_ROLE_PREFIX, clientRolePrefix);
return mapper; return mapper;
......
...@@ -58,10 +58,9 @@ public class UserPropertyMapper extends AbstractCASProtocolMapper { ...@@ -58,10 +58,9 @@ public class UserPropertyMapper extends AbstractCASProtocolMapper {
} }
public static ProtocolMapperModel create(String name, String userAttribute, public static ProtocolMapperModel create(String name, String userAttribute,
String tokenClaimName, String claimType, String tokenClaimName, String claimType) {
boolean consentRequired, String consentText) {
ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName, ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
claimType, consentRequired, consentText, PROVIDER_ID); claimType, PROVIDER_ID);
mapper.getConfig().put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute); mapper.getConfig().put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute);
return mapper; return mapper;
} }
......
...@@ -60,7 +60,7 @@ public class UserRealmRoleMappingMapper extends AbstractUserRoleMappingMapper { ...@@ -60,7 +60,7 @@ public class UserRealmRoleMappingMapper extends AbstractUserRoleMappingMapper {
public static ProtocolMapperModel create(String realmRolePrefix, String name, String tokenClaimName) { public static ProtocolMapperModel create(String realmRolePrefix, String name, String tokenClaimName) {
ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, 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); mapper.getConfig().put(ProtocolMapperUtils.USER_MODEL_REALM_ROLE_MAPPING_ROLE_PREFIX, realmRolePrefix);
return mapper; return mapper;
} }
......
...@@ -63,10 +63,9 @@ public class UserSessionNoteMapper extends AbstractCASProtocolMapper { ...@@ -63,10 +63,9 @@ public class UserSessionNoteMapper extends AbstractCASProtocolMapper {
public static ProtocolMapperModel create(String name, public static ProtocolMapperModel create(String name,
String userSessionNote, String userSessionNote,
String tokenClaimName, String jsonType, String tokenClaimName, String jsonType) {
boolean consentRequired, String consentText) {
ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName, ProtocolMapperModel mapper = CASAttributeMapperHelper.createClaimMapper(name, tokenClaimName,
jsonType, consentRequired, consentText, PROVIDER_ID); jsonType, PROVIDER_ID);
mapper.getConfig().put(ProtocolMapperUtils.USER_SESSION_NOTE, userSessionNote); mapper.getConfig().put(ProtocolMapperUtils.USER_SESSION_NOTE, userSessionNote);
return mapper; return mapper;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment