keycloak-aplcache
Changes
saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/AttributeStatementHelper.java 4(+2 -2)
saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/HardcodedAttributeMapper.java 85(+85 -0)
saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLBasicRoleListMapper.java 29(+23 -6)
saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLBasicRoleNameMapper.java 20(+20 -0)
Details
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/AttributeStatementHelper.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/AttributeStatementHelper.java
index b5850a5..06b299a 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/AttributeStatementHelper.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/AttributeStatementHelper.java
@@ -73,14 +73,14 @@ public class AttributeStatementHelper {
}
public static ProtocolMapperModel createAttributeMapper(String name, String userAttribute, String samlAttributeName, String nameFormat, String friendlyName, boolean consentRequired, String consentText, String mapperId) {
- ProtocolMapperModel mapper = mapper = new ProtocolMapperModel();
+ ProtocolMapperModel mapper = new ProtocolMapperModel();
mapper.setName(name);
mapper.setProtocolMapper(mapperId);
mapper.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
mapper.setConsentRequired(consentRequired);
mapper.setConsentText(consentText);
Map<String, String> config = new HashMap<String, String>();
- config.put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute);
+ if (userAttribute != null) config.put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute);
config.put(SAML_ATTRIBUTE_NAME, samlAttributeName);
if (friendlyName != null) {
config.put(FRIENDLY_NAME, friendlyName);
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/HardcodedAttributeMapper.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/HardcodedAttributeMapper.java
new file mode 100755
index 0000000..221bcfd
--- /dev/null
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/HardcodedAttributeMapper.java
@@ -0,0 +1,85 @@
+package org.keycloak.protocol.saml.mappers;
+
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.protocol.ProtocolMapperUtils;
+import org.picketlink.identity.federation.saml.v2.assertion.AttributeStatementType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Mappings UserModel property (the property name of a getter method) to an AttributeStatement.
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class HardcodedAttributeMapper extends AbstractSAMLProtocolMapper implements SAMLAttributeStatementMapper {
+ public static final String PROVIDER_ID = "saml-hardcode-attribute-mapper";
+ public static final String ATTRIBUTE_VALUE = "attribute.value";
+ private static final List<ConfigProperty> configProperties = new ArrayList<ConfigProperty>();
+
+ static {
+ ConfigProperty property;
+ property = new ConfigProperty();
+ property.setName(ProtocolMapperUtils.USER_ATTRIBUTE);
+ property.setLabel(ProtocolMapperUtils.USER_MODEL_ATTRIBUTE_LABEL);
+ property.setHelpText(ProtocolMapperUtils.USER_MODEL_ATTRIBUTE_HELP_TEXT);
+ configProperties.add(property);
+ AttributeStatementHelper.setConfigProperties(configProperties);
+ property = new ConfigProperty();
+ property.setName(ATTRIBUTE_VALUE);
+ property.setLabel("Attribute value");
+ property.setType(ConfigProperty.STRING_TYPE);
+ property.setHelpText("Value of the attribute you want to hard code.");
+ configProperties.add(property);
+
+ }
+
+
+
+ public List<ConfigProperty> getConfigProperties() {
+ return configProperties;
+ }
+ @Override
+ public String getId() {
+ return PROVIDER_ID;
+ }
+
+ @Override
+ public String getDisplayType() {
+ return "Hardcoded attribute";
+ }
+
+ @Override
+ public String getDisplayCategory() {
+ return AttributeStatementHelper.ATTRIBUTE_STATEMENT_CATEGORY;
+ }
+
+ @Override
+ public String getHelpText() {
+ return "Hardcode an attribute into the SAML Assertion.";
+ }
+
+ @Override
+ public void transformAttributeStatement(AttributeStatementType attributeStatement, ProtocolMapperModel mappingModel, KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession) {
+ String attributeValue = mappingModel.getConfig().get(ATTRIBUTE_VALUE);
+ AttributeStatementHelper.addAttribute(attributeStatement, mappingModel, attributeValue);
+
+ }
+
+ public static ProtocolMapperModel create(String name,
+ String samlAttributeName, String nameFormat, String friendlyName, String value,
+ boolean consentRequired, String consentText) {
+ String mapperId = PROVIDER_ID;
+ ProtocolMapperModel model = AttributeStatementHelper.createAttributeMapper(name, null, samlAttributeName, nameFormat, friendlyName,
+ consentRequired, consentText, mapperId);
+ model.getConfig().put(ATTRIBUTE_VALUE, value);
+ return model;
+
+ }
+
+}
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/HardcodedRole.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/HardcodedRole.java
new file mode 100755
index 0000000..862a0ca
--- /dev/null
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/HardcodedRole.java
@@ -0,0 +1,76 @@
+package org.keycloak.protocol.saml.mappers;
+
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.protocol.ProtocolMapperUtils;
+import org.keycloak.protocol.saml.SamlProtocol;
+import org.picketlink.identity.federation.saml.v2.assertion.AttributeStatementType;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Mappings UserModel property (the property name of a getter method) to an AttributeStatement.
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class HardcodedRole extends AbstractSAMLProtocolMapper {
+ public static final String PROVIDER_ID = "saml-hardcode-role-mapper";
+ public static final String ATTRIBUTE_VALUE = "attribute.value";
+ private static final List<ConfigProperty> configProperties = new ArrayList<ConfigProperty>();
+
+ static {
+ ConfigProperty property;
+ property = new ConfigProperty();
+ property.setName("role");
+ property.setLabel("Role");
+ property.setHelpText("Role name you want to hardcode.");
+ property.setType(ConfigProperty.STRING_TYPE);
+ configProperties.add(property);
+ }
+
+
+
+ public List<ConfigProperty> getConfigProperties() {
+ return configProperties;
+ }
+ @Override
+ public String getId() {
+ return PROVIDER_ID;
+ }
+
+ @Override
+ public String getDisplayType() {
+ return "Hardcoded role";
+ }
+
+ @Override
+ public String getDisplayCategory() {
+ return AttributeStatementHelper.ATTRIBUTE_STATEMENT_CATEGORY;
+ }
+
+ @Override
+ public String getHelpText() {
+ return "Hardcode role into SAML Assertion.";
+ }
+
+ public static ProtocolMapperModel create(String name,
+ String role) {
+ String mapperId = PROVIDER_ID;
+ ProtocolMapperModel mapper = new ProtocolMapperModel();
+ mapper.setName(name);
+ mapper.setProtocolMapper(mapperId);
+ mapper.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
+ Map<String, String> config = new HashMap<String, String>();
+ config.put("role", role);
+ mapper.setConfig(config);
+ return mapper;
+
+ }
+
+}
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLBasicRoleListMapper.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLBasicRoleListMapper.java
index 9895944..7f47195 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLBasicRoleListMapper.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLBasicRoleListMapper.java
@@ -14,6 +14,7 @@ import org.picketlink.identity.federation.saml.v2.assertion.AttributeType;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -92,17 +93,33 @@ public class SAMLBasicRoleListMapper extends AbstractSAMLProtocolMapper implemen
String single = mappingModel.getConfig().get(SINGLE_ROLE_ATTRIBUTE);
boolean singleAttribute = Boolean.parseBoolean(single);
- Map<ProtocolMapperModel, SAMLRoleNameMapper> roleNameMappers = new HashMap<>();
+ List<SamlProtocol.ProtocolMapperProcessor<SAMLRoleNameMapper>> roleNameMappers = new LinkedList<>();
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
+ AttributeType singleAttributeType = null;
for (ProtocolMapperModel mapping : clientSession.getClient().getProtocolMappers()) {
if (!mapping.getProtocol().equals(SamlProtocol.LOGIN_PROTOCOL)) continue;
ProtocolMapper mapper = (ProtocolMapper)sessionFactory.getProviderFactory(ProtocolMapper.class, mapping.getProtocolMapper());
- if (mapper == null || !(mapper instanceof SAMLRoleNameMapper)) continue;
- roleNameMappers.put(mapping, (SAMLRoleNameMapper)mapper);
+ if (mapper == null) continue;
+ if (mapper instanceof SAMLRoleNameMapper) {
+ roleNameMappers.add(new SamlProtocol.ProtocolMapperProcessor<>((SAMLRoleNameMapper) mapper,mapping));
+ }
+ if (mapper instanceof HardcodedRole) {
+ AttributeType attributeType = null;
+ if (singleAttribute) {
+ if (singleAttributeType == null) {
+ singleAttributeType = AttributeStatementHelper.createAttributeType(mappingModel);
+ roleAttributeStatement.addAttribute(new AttributeStatementType.ASTChoiceType(singleAttributeType));
+ }
+ attributeType = singleAttributeType;
+ } else {
+ attributeType = AttributeStatementHelper.createAttributeType(mappingModel);
+ roleAttributeStatement.addAttribute(new AttributeStatementType.ASTChoiceType(attributeType));
+ }
+ attributeType.addAttributeValue(mapping.getConfig().get("role"));
+ }
}
- AttributeType singleAttributeType = null;
for (String roleId : clientSession.getRoles()) {
// todo need a role mapping
RoleModel roleModel = clientSession.getRealm().getRoleById(roleId);
@@ -118,8 +135,8 @@ public class SAMLBasicRoleListMapper extends AbstractSAMLProtocolMapper implemen
roleAttributeStatement.addAttribute(new AttributeStatementType.ASTChoiceType(attributeType));
}
String roleName = roleModel.getName();
- for (Map.Entry<ProtocolMapperModel, SAMLRoleNameMapper> entry : roleNameMappers.entrySet()) {
- String newName = entry.getValue().mapName(entry.getKey(), roleModel);
+ for (SamlProtocol.ProtocolMapperProcessor<SAMLRoleNameMapper> entry : roleNameMappers) {
+ String newName = entry.mapper.mapName(entry.model, roleModel);
if (newName != null) {
roleName = newName;
break;
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLBasicRoleNameMapper.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLBasicRoleNameMapper.java
index b56cf1f..52222ef 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLBasicRoleNameMapper.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/SAMLBasicRoleNameMapper.java
@@ -5,9 +5,12 @@ import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.protocol.oidc.mappers.AbstractOIDCProtocolMapper;
+import org.keycloak.protocol.saml.SamlProtocol;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* Map an assigned role to a different position and name in the token
@@ -88,4 +91,21 @@ public class SAMLBasicRoleNameMapper extends AbstractOIDCProtocolMapper implemen
if (roleModel.getName().equals(role)) return newName;
return null;
}
+
+ public static ProtocolMapperModel create(String name,
+ String role,
+ String newName) {
+ String mapperId = PROVIDER_ID;
+ ProtocolMapperModel mapper = new ProtocolMapperModel();
+ mapper.setName(name);
+ mapper.setProtocolMapper(mapperId);
+ mapper.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
+ Map<String, String> config = new HashMap<String, String>();
+ config.put(ROLE_CONFIG, role);
+ config.put(NEW_ROLE_NAME, newName);
+ mapper.setConfig(config);
+ return mapper;
+
+ }
+
}
diff --git a/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper b/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
index 62f8079..52f5d7c 100755
--- a/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
+++ b/saml/saml-protocol/src/main/resources/META-INF/services/org.keycloak.protocol.ProtocolMapper
@@ -1,5 +1,7 @@
org.keycloak.protocol.saml.mappers.SAMLBasicRoleListMapper
org.keycloak.protocol.saml.mappers.SAMLBasicRoleNameMapper
+org.keycloak.protocol.saml.mappers.HardcodedRole
+org.keycloak.protocol.saml.mappers.HardcodedAttributeMapper
org.keycloak.protocol.saml.mappers.UserAttributeStatementMapper
org.keycloak.protocol.saml.mappers.UserPropertyAttributeStatementMapper
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddClaimMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddClaimMapper.java
index fad7bd6..76fe47d 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddClaimMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAddClaimMapper.java
@@ -76,7 +76,7 @@ public class OIDCAddClaimMapper extends AbstractOIDCProtocolMapper implements OI
@Override
public String getDisplayType() {
- return "Hard coded claim";
+ return "Hardcoded claim";
}
@Override
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
index b6adb01..c81dbef 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
@@ -16,7 +16,10 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.protocol.saml.mappers.AttributeStatementHelper;
+import org.keycloak.protocol.saml.mappers.HardcodedAttributeMapper;
+import org.keycloak.protocol.saml.mappers.HardcodedRole;
import org.keycloak.protocol.saml.mappers.SAMLBasicRoleListMapper;
+import org.keycloak.protocol.saml.mappers.SAMLBasicRoleNameMapper;
import org.keycloak.representations.AccessToken;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.admin.AdminRoot;
@@ -265,6 +268,9 @@ public class SamlBindingTest {
app.addProtocolMapper(mapper);
}
}
+ app.addProtocolMapper(HardcodedAttributeMapper.create("hardcoded-attribute", "hardcoded-attribute", "Basic", null, "hard", false, null));
+ app.addProtocolMapper(HardcodedRole.create("hardcoded-role", "hardcoded-role"));
+ app.addProtocolMapper(SAMLBasicRoleNameMapper.create("renamed-role","manager", "el-jefe"));
}
}, "demo");
@@ -287,6 +293,8 @@ public class SamlBindingTest {
boolean userRole = false;
boolean managerRole = false;
boolean single = false;
+ boolean hardcodedRole = false;
+ boolean hardcodedAttribute = false;
for (AttributeStatementType statement : assertion.getAttributeStatements()) {
for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
AttributeType attr = choice.getAttribute();
@@ -294,14 +302,21 @@ public class SamlBindingTest {
if (single) Assert.fail("too many role attributes");
single = true;
for (Object value : attr.getAttributeValue()) {
- if (value.equals("manager")) managerRole = true;
+ if (value.equals("el-jefe")) managerRole = true;
if (value.equals("user")) userRole = true;
+ if (value.equals("hardcoded-role")) hardcodedRole = true;
}
+ } else if (attr.getName().equals("hardcoded-attribute")) {
+ hardcodedAttribute = true;
+ Assert.assertEquals(attr.getAttributeValue().get(0), "hard");
}
}
}
+ Assert.assertTrue(single);
+ Assert.assertTrue(hardcodedAttribute);
+ Assert.assertTrue(hardcodedRole);
Assert.assertTrue(userRole);
Assert.assertTrue(managerRole);
}