Skip to content
This repository has been archived by the owner on Oct 12, 2020. It is now read-only.

Commit

Permalink
update for KEYCLOAK-6630 Client scopes initial support
Browse files Browse the repository at this point in the history
  • Loading branch information
Doccrazy committed Jun 17, 2018
1 parent 2dc9e53 commit b8d6860
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ public CASLoginProtocol setEventBuilder(EventBuilder event) {
}

@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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,22 @@

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);

Expand All @@ -43,51 +41,45 @@ public LoginProtocol create(KeycloakSession session) {
}

@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
protected void addDefaults(ClientModel client) {
for (ProtocolMapperModel model : defaultBuiltins) client.addProtocolMapper(model);
Expand Down Expand Up @@ -116,9 +108,4 @@ public void setupClientDefaults(ClientRepresentation rep, ClientModel newClient)
newClient.setManagementUrl(rep.getRootUrl());
}
}

@Override
public void setupTemplateDefaults(ClientTemplateRepresentation clientRep, ClientTemplateModel newClient) {

}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
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;
import org.keycloak.protocol.cas.utils.CASValidationException;
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;
Expand All @@ -29,8 +27,10 @@ public ServiceValidateEndpoint(RealmModel realm, EventBuilder event) {
@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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel map
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,9 @@ public static boolean useFullPath(ProtocolMapperModel mappingModel) {
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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel map

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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -78,27 +79,18 @@ private static Predicate<RoleModel> getClientRoleFilter(String clientId, UserSes
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;
}

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);
Expand All @@ -107,7 +99,7 @@ private static Predicate<RoleModel> getClientRoleFilter(String clientId, UserSes
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,9 @@ public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel map
}

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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel map

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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,9 @@ public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel map

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;
}
Expand Down

0 comments on commit b8d6860

Please sign in to comment.