More options to organization scope mapper including adding organization attributes to tokens
Closes #31642 Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
parent
bacfeed7b1
commit
449557290b
4 changed files with 267 additions and 53 deletions
|
@ -3239,4 +3239,6 @@ userInvitedOrganization_other={{count}} invites to users sent
|
||||||
sentInvitation=Sent invitation
|
sentInvitation=Sent invitation
|
||||||
loggedInAsTempAdminUser=You are logged in as a temporary admin user. To harden security, create a permanent admin account and delete the temporary one.
|
loggedInAsTempAdminUser=You are logged in as a temporary admin user. To harden security, create a permanent admin account and delete the temporary one.
|
||||||
temporaryAdmin=Temporary admin user account. Ensure it is replaced with a permanent admin user account as soon as possible.
|
temporaryAdmin=Temporary admin user account. Ensure it is replaced with a permanent admin user account as soon as possible.
|
||||||
temporaryService=Temporary admin service account. Ensure it is replaced with a permanent admin service account as soon as possible.
|
temporaryService=Temporary admin service account. Ensure it is replaced with a permanent admin service account as soon as possible.
|
||||||
|
addOrganizationAttributes.label=Add organization attributes
|
||||||
|
addOrganizationAttributes.help=If enabled, the organization attributes will be available for each organization mapped to the token.
|
|
@ -17,22 +17,30 @@
|
||||||
|
|
||||||
package org.keycloak.organization.protocol.mappers.oidc;
|
package org.keycloak.organization.protocol.mappers.oidc;
|
||||||
|
|
||||||
|
import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.JSON_TYPE;
|
||||||
|
import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME;
|
||||||
|
|
||||||
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 java.util.Objects;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.models.ClientSessionContext;
|
import org.keycloak.models.ClientSessionContext;
|
||||||
|
import org.keycloak.models.KeycloakContext;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.OrganizationModel;
|
import org.keycloak.models.OrganizationModel;
|
||||||
import org.keycloak.models.ProtocolMapperModel;
|
import org.keycloak.models.ProtocolMapperModel;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
|
import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
|
import org.keycloak.models.utils.RepresentationToModel;
|
||||||
import org.keycloak.organization.OrganizationProvider;
|
import org.keycloak.organization.OrganizationProvider;
|
||||||
|
import org.keycloak.protocol.ProtocolMapperUtils;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
import org.keycloak.protocol.oidc.mappers.AbstractOIDCProtocolMapper;
|
import org.keycloak.protocol.oidc.mappers.AbstractOIDCProtocolMapper;
|
||||||
import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
|
import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
|
||||||
|
@ -47,11 +55,28 @@ import org.keycloak.representations.IDToken;
|
||||||
public class OrganizationMembershipMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper, EnvironmentDependentProviderFactory {
|
public class OrganizationMembershipMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper, EnvironmentDependentProviderFactory {
|
||||||
|
|
||||||
public static final String PROVIDER_ID = "oidc-organization-membership-mapper";
|
public static final String PROVIDER_ID = "oidc-organization-membership-mapper";
|
||||||
|
public static final String ADD_ORGANIZATION_ATTRIBUTES = "addOrganizationAttributes";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ProviderConfigProperty> getConfigProperties() {
|
public List<ProviderConfigProperty> getConfigProperties() {
|
||||||
List<ProviderConfigProperty> properties = new ArrayList<>();
|
List<ProviderConfigProperty> properties = new ArrayList<>();
|
||||||
|
OIDCAttributeMapperHelper.addTokenClaimNameConfig(properties);
|
||||||
OIDCAttributeMapperHelper.addIncludeInTokensConfig(properties, OrganizationMembershipMapper.class);
|
OIDCAttributeMapperHelper.addIncludeInTokensConfig(properties, OrganizationMembershipMapper.class);
|
||||||
|
OIDCAttributeMapperHelper.addJsonTypeConfig(properties, List.of("String", "JSON"), "String");
|
||||||
|
ProviderConfigProperty property = new ProviderConfigProperty();
|
||||||
|
property.setName(ProtocolMapperUtils.MULTIVALUED);
|
||||||
|
property.setLabel(ProtocolMapperUtils.MULTIVALUED_LABEL);
|
||||||
|
property.setHelpText(ProtocolMapperUtils.MULTIVALUED_HELP_TEXT);
|
||||||
|
property.setType(ProviderConfigProperty.BOOLEAN_TYPE);
|
||||||
|
property.setDefaultValue(Boolean.TRUE.toString());
|
||||||
|
properties.add(property);
|
||||||
|
property = new ProviderConfigProperty();
|
||||||
|
property.setName(ADD_ORGANIZATION_ATTRIBUTES);
|
||||||
|
property.setLabel(ADD_ORGANIZATION_ATTRIBUTES + ".label");
|
||||||
|
property.setType(ProviderConfigProperty.BOOLEAN_TYPE);
|
||||||
|
property.setDefaultValue(Boolean.FALSE.toString());
|
||||||
|
property.setHelpText(ADD_ORGANIZATION_ATTRIBUTES + ".help");
|
||||||
|
properties.add(property);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +101,7 @@ public class OrganizationMembershipMapper extends AbstractOIDCProtocolMapper imp
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession, KeycloakSession session, ClientSessionContext clientSessionCtx) {
|
protected void setClaim(IDToken token, ProtocolMapperModel model, UserSessionModel userSession, KeycloakSession session, ClientSessionContext clientSessionCtx) {
|
||||||
String rawScopes = clientSessionCtx.getScopeString();
|
String rawScopes = clientSessionCtx.getScopeString();
|
||||||
OrganizationScope scope = OrganizationScope.valueOfScope(rawScopes);
|
OrganizationScope scope = OrganizationScope.valueOfScope(rawScopes);
|
||||||
|
|
||||||
|
@ -93,16 +118,94 @@ public class OrganizationMembershipMapper extends AbstractOIDCProtocolMapper imp
|
||||||
organizations = Stream.of(session.getProvider(OrganizationProvider.class).getById(orgId));
|
organizations = Stream.of(session.getProvider(OrganizationProvider.class).getById(orgId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeycloakContext context = session.getContext();
|
||||||
|
RealmModel realm = context.getRealm();
|
||||||
|
ProtocolMapperModel effectiveModel = getEffectiveModel(session, realm, model);
|
||||||
|
|
||||||
Map<String, Map<String, Object>> claim = new HashMap<>();
|
Object claim = resolveValue(effectiveModel, organizations.toList());
|
||||||
|
|
||||||
organizations.filter(Objects::nonNull).forEach(o -> claim.put(o.getAlias(), Map.of()));
|
if (claim == null) {
|
||||||
|
|
||||||
if (claim.isEmpty()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
token.getOtherClaims().put(OAuth2Constants.ORGANIZATION, claim);
|
OIDCAttributeMapperHelper.mapClaim(token, effectiveModel, claim);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object resolveValue(ProtocolMapperModel model, List<OrganizationModel> organizations) {
|
||||||
|
if (organizations.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!OIDCAttributeMapperHelper.isMultivalued(model)) {
|
||||||
|
return organizations.get(0).getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Map<String, Object>> value = new HashMap<>();
|
||||||
|
|
||||||
|
for (OrganizationModel o : organizations) {
|
||||||
|
if (o == null || !o.isEnabled()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> attributes = Map.of();
|
||||||
|
|
||||||
|
if (isAddOrganizationAttributes(model)) {
|
||||||
|
attributes = new HashMap<>(o.getAttributes());
|
||||||
|
}
|
||||||
|
|
||||||
|
value.put(o.getAlias(), attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isJsonType(model)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isJsonType(ProtocolMapperModel model) {
|
||||||
|
return "JSON".equals(model.getConfig().getOrDefault(JSON_TYPE, "JSON"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProtocolMapperModel getEffectiveModel(KeycloakSession session, RealmModel realm, ProtocolMapperModel model) {
|
||||||
|
// Effectively clone
|
||||||
|
ProtocolMapperModel copy = RepresentationToModel.toModel(ModelToRepresentation.toRepresentation(model));
|
||||||
|
Map<String, String> config = Optional.ofNullable(copy.getConfig()).orElseGet(HashMap::new);
|
||||||
|
|
||||||
|
config.putIfAbsent(JSON_TYPE, "String");
|
||||||
|
|
||||||
|
if (!OIDCAttributeMapperHelper.isMultivalued(copy)) {
|
||||||
|
config.put(ADD_ORGANIZATION_ATTRIBUTES, Boolean.FALSE.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAddOrganizationAttributes(copy)) {
|
||||||
|
config.put(JSON_TYPE, "JSON");
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefaultValues(config);
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDefaultValues(Map<String, String> config) {
|
||||||
|
config.putIfAbsent(TOKEN_CLAIM_NAME, OAuth2Constants.ORGANIZATION);
|
||||||
|
|
||||||
|
for (ProviderConfigProperty property : getConfigProperties()) {
|
||||||
|
Object defaultValue = property.getDefaultValue();
|
||||||
|
|
||||||
|
if (defaultValue != null) {
|
||||||
|
config.putIfAbsent(ProtocolMapperUtils.MULTIVALUED, defaultValue.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAddOrganizationAttributes(ProtocolMapperModel model) {
|
||||||
|
return Boolean.parseBoolean(model.getConfig().getOrDefault(ADD_ORGANIZATION_ATTRIBUTES, Boolean.FALSE.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProtocolMapperModel create(String name, boolean accessToken, boolean idToken, boolean introspectionEndpoint) {
|
public static ProtocolMapperModel create(String name, boolean accessToken, boolean idToken, boolean introspectionEndpoint) {
|
||||||
|
@ -114,6 +217,9 @@ public class OrganizationMembershipMapper extends AbstractOIDCProtocolMapper imp
|
||||||
if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
|
if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
|
||||||
if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
|
if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
|
||||||
if (introspectionEndpoint) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION, "true");
|
if (introspectionEndpoint) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION, "true");
|
||||||
|
config.put(TOKEN_CLAIM_NAME, OAuth2Constants.ORGANIZATION);
|
||||||
|
config.put(JSON_TYPE, "String");
|
||||||
|
config.put(ProtocolMapperUtils.MULTIVALUED, Boolean.TRUE.toString());
|
||||||
mapper.setConfig(config);
|
mapper.setConfig(config);
|
||||||
|
|
||||||
return mapper;
|
return mapper;
|
||||||
|
|
|
@ -442,18 +442,17 @@ public class OIDCAttributeMapperHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addJsonTypeConfig(List<ProviderConfigProperty> configProperties) {
|
public static void addJsonTypeConfig(List<ProviderConfigProperty> configProperties) {
|
||||||
|
addJsonTypeConfig(configProperties, List.of("String", "long", "int", "boolean", "JSON"), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addJsonTypeConfig(List<ProviderConfigProperty> configProperties, List<String> supportedTypes, String defaultValue) {
|
||||||
ProviderConfigProperty property = new ProviderConfigProperty();
|
ProviderConfigProperty property = new ProviderConfigProperty();
|
||||||
property.setName(JSON_TYPE);
|
property.setName(JSON_TYPE);
|
||||||
property.setLabel(JSON_TYPE);
|
property.setLabel(JSON_TYPE);
|
||||||
List<String> types = new ArrayList<>(5);
|
|
||||||
types.add("String");
|
|
||||||
types.add("long");
|
|
||||||
types.add("int");
|
|
||||||
types.add("boolean");
|
|
||||||
types.add("JSON");
|
|
||||||
property.setType(ProviderConfigProperty.LIST_TYPE);
|
property.setType(ProviderConfigProperty.LIST_TYPE);
|
||||||
property.setOptions(types);
|
property.setOptions(supportedTypes);
|
||||||
property.setHelpText(JSON_TYPE_TOOLTIP);
|
property.setHelpText(JSON_TYPE_TOOLTIP);
|
||||||
|
property.setDefaultValue(defaultValue);
|
||||||
configProperties.add(property);
|
configProperties.add(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,14 @@
|
||||||
package org.keycloak.testsuite.organization.mapper;
|
package org.keycloak.testsuite.organization.mapper;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.hasItem;
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
import static org.hamcrest.Matchers.oneOf;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
@ -31,24 +33,31 @@ import static org.junit.Assert.assertTrue;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.TokenVerifier;
|
import org.keycloak.TokenVerifier;
|
||||||
import org.keycloak.admin.client.resource.ClientResource;
|
import org.keycloak.admin.client.resource.ClientResource;
|
||||||
|
import org.keycloak.admin.client.resource.ClientScopeResource;
|
||||||
import org.keycloak.admin.client.resource.OrganizationResource;
|
import org.keycloak.admin.client.resource.OrganizationResource;
|
||||||
import org.keycloak.common.Profile.Feature;
|
import org.keycloak.common.Profile.Feature;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
import org.keycloak.common.util.UriUtils;
|
import org.keycloak.common.util.UriUtils;
|
||||||
import org.keycloak.models.OrganizationModel;
|
import org.keycloak.models.OrganizationModel;
|
||||||
|
import org.keycloak.organization.protocol.mappers.oidc.OrganizationMembershipMapper;
|
||||||
|
import org.keycloak.protocol.ProtocolMapperUtils;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
|
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
||||||
import org.keycloak.protocol.oidc.mappers.GroupMembershipMapper;
|
import org.keycloak.protocol.oidc.mappers.GroupMembershipMapper;
|
||||||
import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
|
import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
|
||||||
import org.keycloak.representations.AccessToken;
|
import org.keycloak.representations.AccessToken;
|
||||||
import org.keycloak.representations.RefreshToken;
|
import org.keycloak.representations.RefreshToken;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
|
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||||
import org.keycloak.representations.idm.MemberRepresentation;
|
import org.keycloak.representations.idm.MemberRepresentation;
|
||||||
import org.keycloak.representations.idm.OrganizationRepresentation;
|
import org.keycloak.representations.idm.OrganizationRepresentation;
|
||||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||||
|
@ -62,6 +71,12 @@ import org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse;
|
||||||
@EnableFeature(Feature.ORGANIZATION)
|
@EnableFeature(Feature.ORGANIZATION)
|
||||||
public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest {
|
public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void onBefore() {
|
||||||
|
setMapperConfig(OIDCAttributeMapperHelper.JSON_TYPE, null);
|
||||||
|
setMapperConfig(ProtocolMapperUtils.MULTIVALUED, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPasswordGrantType() throws Exception {
|
public void testPasswordGrantType() throws Exception {
|
||||||
OrganizationResource orga = testRealm().organizations().get(createOrganization("org-a").getId());
|
OrganizationResource orga = testRealm().organizations().get(createOrganization("org-a").getId());
|
||||||
|
@ -85,13 +100,12 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
|
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
|
|
||||||
Map<String, Object> claim = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
List<String> claim = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(claim, notNullValue());
|
assertThat(claim, notNullValue());
|
||||||
assertThat(claim.get(orga.toRepresentation().getName()), notNullValue());
|
String orgaName = orga.toRepresentation().getName();
|
||||||
String orgaId = orga.toRepresentation().getName();
|
String orgbName = orgb.toRepresentation().getName();
|
||||||
String orgbId = orgb.toRepresentation().getName();
|
assertThat(claim.contains(orgaName), is(true));
|
||||||
assertThat(claim.get(orgaId), notNullValue());
|
assertThat(claim.contains(orgbName), is(true));
|
||||||
assertThat(claim.get(orgbId), notNullValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -171,10 +185,10 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
assertThat(accessToken.getScope(), containsString(orgScope));
|
assertThat(accessToken.getScope(), containsString(orgScope));
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
Map<String, Object> organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
List<String> organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(organizations.size(), is(2));
|
assertThat(organizations.size(), is(2));
|
||||||
assertThat(organizations.containsKey(orgA.getAlias()), is(true));
|
assertThat(organizations.contains(orgA.getAlias()), is(true));
|
||||||
assertThat(organizations.containsKey(orgB.getAlias()), is(true));
|
assertThat(organizations.contains(orgB.getAlias()), is(true));
|
||||||
assertThat(response.getRefreshToken(), notNullValue());
|
assertThat(response.getRefreshToken(), notNullValue());
|
||||||
RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
|
RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
|
||||||
assertThat(refreshToken.getScope(), containsString(orgScope));
|
assertThat(refreshToken.getScope(), containsString(orgScope));
|
||||||
|
@ -183,10 +197,10 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
accessToken = oauth.verifyToken(response.getAccessToken());
|
accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
assertThat(accessToken.getScope(), containsString(orgScope));
|
assertThat(accessToken.getScope(), containsString(orgScope));
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(organizations.size(), is(2));
|
assertThat(organizations.size(), is(2));
|
||||||
assertThat(organizations.containsKey(orgA.getAlias()), is(true));
|
assertThat(organizations.contains(orgA.getAlias()), is(true));
|
||||||
assertThat(organizations.containsKey(orgB.getAlias()), is(true));
|
assertThat(organizations.contains(orgB.getAlias()), is(true));
|
||||||
refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
|
refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
|
||||||
assertThat(refreshToken.getScope(), containsString(orgScope));
|
assertThat(refreshToken.getScope(), containsString(orgScope));
|
||||||
}
|
}
|
||||||
|
@ -229,10 +243,10 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
// once we support the user to select an organization, the selected organization will be mapped
|
// once we support the user to select an organization, the selected organization will be mapped
|
||||||
assertThat(response.getScope(), containsString("organization"));
|
assertThat(response.getScope(), containsString("organization"));
|
||||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
Map<String, Object> organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
List<String> organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
assertThat(organizations.containsKey(orgA.getAlias()), is(false));
|
assertThat(organizations.contains(orgA.getAlias()), is(false));
|
||||||
assertThat(organizations.containsKey(orgB.getAlias()), is(true));
|
assertThat(organizations.contains(orgB.getAlias()), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -254,7 +268,7 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
assertThat(accessToken.getScope(), containsString(orgScope));
|
assertThat(accessToken.getScope(), containsString(orgScope));
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
Map<String, Object> organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
List<String> organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(organizations.size(), is(2));
|
assertThat(organizations.size(), is(2));
|
||||||
orgScope = "organization:orga";
|
orgScope = "organization:orga";
|
||||||
oauth.scope(orgScope);
|
oauth.scope(orgScope);
|
||||||
|
@ -263,9 +277,9 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
accessToken = oauth.verifyToken(response.getAccessToken());
|
accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
assertThat(accessToken.getScope(), containsString(orgScope));
|
assertThat(accessToken.getScope(), containsString(orgScope));
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(organizations.size(), is(1));
|
assertThat(organizations.size(), is(1));
|
||||||
assertThat(organizations.containsKey(orgA.getAlias()), is(true));
|
assertThat(organizations.contains(orgA.getAlias()), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -288,9 +302,9 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
assertThat(accessToken.getScope(), containsString(orgScope));
|
assertThat(accessToken.getScope(), containsString(orgScope));
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
Map<String, Object> organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
List<String> organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(organizations.size(), is(1));
|
assertThat(organizations.size(), is(1));
|
||||||
assertThat(organizations.containsKey(orgA.getAlias()), is(true));
|
assertThat(organizations.contains(orgA.getAlias()), is(true));
|
||||||
orgScope = "organization:*";
|
orgScope = "organization:*";
|
||||||
oauth.scope(orgScope);
|
oauth.scope(orgScope);
|
||||||
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
||||||
|
@ -298,9 +312,9 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
accessToken = oauth.verifyToken(response.getAccessToken());
|
accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
assertThat(accessToken.getScope(), containsString(originalScope));
|
assertThat(accessToken.getScope(), containsString(originalScope));
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(organizations.size(), is(1));
|
assertThat(organizations.size(), is(1));
|
||||||
assertThat(organizations.containsKey(orgA.getAlias()), is(true));
|
assertThat(organizations.contains(orgA.getAlias()), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -323,9 +337,9 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
assertThat(accessToken.getScope(), containsString(orgScope));
|
assertThat(accessToken.getScope(), containsString(orgScope));
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
Map<String, Object> organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
List<String> organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(organizations.size(), is(1));
|
assertThat(organizations.size(), is(1));
|
||||||
assertThat(organizations.containsKey(orgA.getAlias()), is(true));
|
assertThat(organizations.contains(orgA.getAlias()), is(true));
|
||||||
orgScope = "organization:orgb";
|
orgScope = "organization:orgb";
|
||||||
oauth.scope(orgScope);
|
oauth.scope(orgScope);
|
||||||
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
||||||
|
@ -358,9 +372,9 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
// once we support the user to select an organization, the selected organization will be mapped
|
// once we support the user to select an organization, the selected organization will be mapped
|
||||||
assertThat(response.getScope(), containsString("organization"));
|
assertThat(response.getScope(), containsString("organization"));
|
||||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
Map<String, Object> organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
assertThat(organizations.containsKey(orgB.getAlias()), is(true));
|
List<String> organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
|
assertThat(organizations.contains(orgB.getAlias()), is(true));
|
||||||
String orgScope = "organization:*";
|
String orgScope = "organization:*";
|
||||||
oauth.scope(orgScope);
|
oauth.scope(orgScope);
|
||||||
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
||||||
|
@ -368,8 +382,8 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
accessToken = oauth.verifyToken(response.getAccessToken());
|
accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
assertThat(accessToken.getScope(), containsString(originalScope));
|
assertThat(accessToken.getScope(), containsString(originalScope));
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(organizations.containsKey(orgB.getAlias()), is(true));
|
assertThat(organizations.contains(orgB.getAlias()), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -390,13 +404,11 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
loginPage.login(memberPassword);
|
loginPage.login(memberPassword);
|
||||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
AccessTokenResponse response = oauth.doAccessTokenRequest(code, KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
||||||
// for now, return the organization scope in the response and access token even though no organization is mapped into the token
|
|
||||||
// once we support the user to select an organization, the selected organization will be mapped
|
|
||||||
assertThat(response.getScope(), containsString("organization"));
|
assertThat(response.getScope(), containsString("organization"));
|
||||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
Map<String, Object> organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
assertThat(organizations.containsKey(orgB.getAlias()), is(true));
|
List<String> organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
|
assertThat(organizations.contains(orgB.getAlias()), is(true));
|
||||||
String orgScope = "organization:orgb";
|
String orgScope = "organization:orgb";
|
||||||
oauth.scope(orgScope);
|
oauth.scope(orgScope);
|
||||||
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
||||||
|
@ -406,6 +418,80 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), not(hasItem(OAuth2Constants.ORGANIZATION)));
|
assertThat(accessToken.getOtherClaims().keySet(), not(hasItem(OAuth2Constants.ORGANIZATION)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIncludeOrganizationAttributes() throws Exception {
|
||||||
|
OrganizationResource organization = testRealm().organizations().get(createOrganization().getId());
|
||||||
|
addMember(organization);
|
||||||
|
setMapperConfig(OrganizationMembershipMapper.ADD_ORGANIZATION_ATTRIBUTES, Boolean.TRUE.toString());
|
||||||
|
|
||||||
|
oauth.clientId("direct-grant");
|
||||||
|
oauth.scope("openid organization");
|
||||||
|
AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", memberEmail, memberPassword);
|
||||||
|
assertThat(response.getScope(), containsString("organization"));
|
||||||
|
AccessToken accessToken = TokenVerifier.create(response.getAccessToken(), AccessToken.class).getToken();
|
||||||
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
|
Map<String, Map<String, List<String>>> organizations = (Map<String, Map<String, List<String>>>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
|
assertThat(organizations.keySet(), hasItem(organizationName));
|
||||||
|
assertThat(organizations.get(organizationName).keySet(), hasItem("key"));
|
||||||
|
assertThat(organizations.get(organizationName).get("key"), containsInAnyOrder("value1", "value2"));
|
||||||
|
|
||||||
|
// when attributes are added to tokens, the claim type is a json regardless of the value set in the config
|
||||||
|
setMapperConfig(OrganizationMembershipMapper.ADD_ORGANIZATION_ATTRIBUTES, Boolean.TRUE.toString());
|
||||||
|
setMapperConfig(OIDCAttributeMapperHelper.JSON_TYPE, "boolean");
|
||||||
|
response = oauth.doGrantAccessTokenRequest("password", memberEmail, memberPassword);
|
||||||
|
accessToken = TokenVerifier.create(response.getAccessToken(), AccessToken.class).getToken();
|
||||||
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
|
organizations = (Map<String, Map<String, List<String>>>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
|
assertThat(organizations.keySet(), hasItem(organizationName));
|
||||||
|
assertThat(organizations.get(organizationName).keySet(), hasItem("key"));
|
||||||
|
assertThat(organizations.get(organizationName).get("key"), containsInAnyOrder("value1", "value2"));
|
||||||
|
|
||||||
|
setMapperConfig(OrganizationMembershipMapper.ADD_ORGANIZATION_ATTRIBUTES, Boolean.FALSE.toString());
|
||||||
|
setMapperConfig(OIDCAttributeMapperHelper.JSON_TYPE, "JSON");
|
||||||
|
response = oauth.doGrantAccessTokenRequest("password", memberEmail, memberPassword);
|
||||||
|
accessToken = TokenVerifier.create(response.getAccessToken(), AccessToken.class).getToken();
|
||||||
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
|
organizations = (Map<String, Map<String, List<String>>>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
|
assertThat(organizations.keySet(), hasItem(organizationName));
|
||||||
|
assertThat(organizations.get(organizationName).keySet().isEmpty(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOrganizationsClaimAsList() throws Exception {
|
||||||
|
OrganizationRepresentation orgA = createOrganization("orga", Map.of(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString()));
|
||||||
|
MemberRepresentation member = addMember(testRealm().organizations().get(orgA.getId()), "member@" + orgA.getDomains().iterator().next().getName());
|
||||||
|
OrganizationRepresentation orgB = createOrganization("orgb", Map.of(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString()));
|
||||||
|
testRealm().organizations().get(orgB.getId()).members().addMember(member.getId()).close();
|
||||||
|
|
||||||
|
setMapperConfig(OIDCAttributeMapperHelper.JSON_TYPE, "String");
|
||||||
|
oauth.clientId("direct-grant");
|
||||||
|
oauth.scope("openid organization:*");
|
||||||
|
AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", member.getEmail(), memberPassword);
|
||||||
|
assertThat(response.getScope(), containsString("organization"));
|
||||||
|
AccessToken accessToken = TokenVerifier.create(response.getAccessToken(), AccessToken.class).getToken();
|
||||||
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
|
List<String> organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
|
assertThat(organizations, containsInAnyOrder("orga", "orgb"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOrganizationsClaimSingleValued() throws Exception {
|
||||||
|
OrganizationRepresentation orgA = createOrganization("orga", Map.of(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString()));
|
||||||
|
MemberRepresentation member = addMember(testRealm().organizations().get(orgA.getId()), "member@" + orgA.getDomains().iterator().next().getName());
|
||||||
|
OrganizationRepresentation orgB = createOrganization("orgb", Map.of(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString()));
|
||||||
|
testRealm().organizations().get(orgB.getId()).members().addMember(member.getId()).close();
|
||||||
|
|
||||||
|
setMapperConfig(ProtocolMapperUtils.MULTIVALUED, Boolean.FALSE.toString());
|
||||||
|
oauth.clientId("direct-grant");
|
||||||
|
oauth.scope("openid organization:*");
|
||||||
|
AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", member.getEmail(), memberPassword);
|
||||||
|
assertThat(response.getScope(), containsString("organization"));
|
||||||
|
AccessToken accessToken = TokenVerifier.create(response.getAccessToken(), AccessToken.class).getToken();
|
||||||
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
|
String organization = (String) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
|
assertThat(organization, is(oneOf("orga", "orgb")));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidOrganizationScope() throws MalformedURLException {
|
public void testInvalidOrganizationScope() throws MalformedURLException {
|
||||||
oauth.clientId("broker-app");
|
oauth.clientId("broker-app");
|
||||||
|
@ -429,16 +515,15 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
return groupMapper;
|
return groupMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertScopeAndClaims(String orgScope, OrganizationRepresentation orgA) {
|
private void assertScopeAndClaims(String orgScope, OrganizationRepresentation org) {
|
||||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
AccessTokenResponse response = oauth.doAccessTokenRequest(code, KcOidcBrokerConfiguration.CONSUMER_BROKER_APP_SECRET);
|
||||||
assertThat(response.getScope(), containsString(orgScope));
|
assertThat(response.getScope(), containsString(orgScope));
|
||||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
assertThat(accessToken.getScope(), containsString(orgScope));
|
assertThat(accessToken.getScope(), containsString(orgScope));
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
Map<String, Object> organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
List<String> organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(organizations.size(), is(1));
|
assertThat(organizations.contains(org.getAlias()), is(true));
|
||||||
assertThat(organizations.containsKey(orgA.getAlias()), is(true));
|
|
||||||
assertThat(response.getRefreshToken(), notNullValue());
|
assertThat(response.getRefreshToken(), notNullValue());
|
||||||
RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
|
RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
|
||||||
assertThat(refreshToken.getScope(), containsString(orgScope));
|
assertThat(refreshToken.getScope(), containsString(orgScope));
|
||||||
|
@ -447,10 +532,32 @@ public class OrganizationOIDCProtocolMapperTest extends AbstractOrganizationTest
|
||||||
accessToken = oauth.verifyToken(response.getAccessToken());
|
accessToken = oauth.verifyToken(response.getAccessToken());
|
||||||
assertThat(accessToken.getScope(), containsString(orgScope));
|
assertThat(accessToken.getScope(), containsString(orgScope));
|
||||||
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
assertThat(accessToken.getOtherClaims().keySet(), hasItem(OAuth2Constants.ORGANIZATION));
|
||||||
organizations = (Map<String, Object>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
organizations = (List<String>) accessToken.getOtherClaims().get(OAuth2Constants.ORGANIZATION);
|
||||||
assertThat(organizations.size(), is(1));
|
assertThat(organizations.size(), is(1));
|
||||||
assertThat(organizations.containsKey(orgA.getAlias()), is(true));
|
assertThat(organizations.contains(org.getAlias()), is(true));
|
||||||
refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
|
refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
|
||||||
assertThat(refreshToken.getScope(), containsString(orgScope));
|
assertThat(refreshToken.getScope(), containsString(orgScope));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setMapperConfig(String key, String value) {
|
||||||
|
ClientScopeRepresentation orgScope = testRealm().clientScopes().findAll().stream()
|
||||||
|
.filter(s -> OIDCLoginProtocolFactory.ORGANIZATION.equals(s.getName()))
|
||||||
|
.findAny()
|
||||||
|
.orElseThrow();
|
||||||
|
ClientScopeResource orgScopeResource = testRealm().clientScopes().get(orgScope.getId());
|
||||||
|
ProtocolMapperRepresentation orgMapper = orgScopeResource.getProtocolMappers().getMappers().stream()
|
||||||
|
.filter(m -> OIDCLoginProtocolFactory.ORGANIZATION.equals(m.getName()))
|
||||||
|
.findAny()
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
|
Map<String, String> config = orgMapper.getConfig();
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
config.remove(key);
|
||||||
|
} else {
|
||||||
|
config.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
orgScopeResource.getProtocolMappers().update(orgMapper.getId(), orgMapper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue