From 58ac3c5921eca81783077edd6c8613f295112f4e Mon Sep 17 00:00:00 2001 From: Luca Filipozzi Date: Sun, 22 Aug 2021 11:02:55 -0700 Subject: [PATCH] add code --- .gitignore | 3 + bundle/pom.xml | 47 +++ .../META-INF/jboss-deployment-structure.xml | 16 + module/pom.xml | 85 +++++ .../RegexRealmAndClientRoleClaimMapper.java | 138 +++++++ ...egexRealmAndClientRoleAttributeMapper.java | 138 +++++++ .../RegexRealmAndClientRoleMapperUtil.java | 113 ++++++ ...oak.broker.provider.IdentityProviderMapper | 4 + pom.xml | 342 ++++++++++++++++++ 9 files changed, 886 insertions(+) create mode 100644 bundle/pom.xml create mode 100644 bundle/src/main/application/META-INF/jboss-deployment-structure.xml create mode 100644 module/pom.xml create mode 100644 module/src/main/java/com/github/lucafilipozzi/keycloak/broker/oidc/mappers/RegexRealmAndClientRoleClaimMapper.java create mode 100644 module/src/main/java/com/github/lucafilipozzi/keycloak/broker/saml/mappers/RegexRealmAndClientRoleAttributeMapper.java create mode 100644 module/src/main/java/com/github/lucafilipozzi/keycloak/broker/util/RegexRealmAndClientRoleMapperUtil.java create mode 100644 module/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore index ea8f090..108912c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ # Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENCE. +# direnv +.envrc + # idea .idea/ *.iml diff --git a/bundle/pom.xml b/bundle/pom.xml new file mode 100644 index 0000000..9642839 --- /dev/null +++ b/bundle/pom.xml @@ -0,0 +1,47 @@ + + + + 4.0.0 + + + com.github.lucafilipozzi + keycloak-regex-mapper + ${revision} + + + keycloak-regex-mapper-bundle + ear + bundle + + + + ${project.parent.groupId} + ${project.parent.artifactId}-module + + + + + + ${project.parent.artifactId}-${revision} + + + org.apache.maven.plugins + maven-ear-plugin + + ${project.parent.artifactId} + ${project.parent.description} + + + ${project.groupId} + ${project.parent.artifactId}-module + + ${project.parent.groupId}-${project.parent.artifactId}-${revision}.jar + true + + + + + + + diff --git a/bundle/src/main/application/META-INF/jboss-deployment-structure.xml b/bundle/src/main/application/META-INF/jboss-deployment-structure.xml new file mode 100644 index 0000000..30dc55c --- /dev/null +++ b/bundle/src/main/application/META-INF/jboss-deployment-structure.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/module/pom.xml b/module/pom.xml new file mode 100644 index 0000000..78eb47d --- /dev/null +++ b/module/pom.xml @@ -0,0 +1,85 @@ + + + + 4.0.0 + + + com.github.lucafilipozzi + keycloak-regex-mapper + ${revision} + + + keycloak-regex-mapper-module + jar + module + + + + + com.google.guava + guava + + + org.jboss.logging + jboss-logging + + + org.keycloak + keycloak-common + + + org.keycloak + keycloak-core + + + org.keycloak + keycloak-saml-core-public + + + org.keycloak + keycloak-server-spi + + + org.keycloak + keycloak-server-spi-private + + + org.keycloak + keycloak-services + + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + org.owasp + dependency-check-maven + + + org.codehaus.mojo + versions-maven-plugin + + + org.apache.maven.plugins + maven-dependency-plugin + + + org.keycloak:keycloak-common + org.keycloak:keycloak-core + org.keycloak:keycloak-server-spi + + + + + org.basepom.maven + duplicate-finder-maven-plugin + + + + diff --git a/module/src/main/java/com/github/lucafilipozzi/keycloak/broker/oidc/mappers/RegexRealmAndClientRoleClaimMapper.java b/module/src/main/java/com/github/lucafilipozzi/keycloak/broker/oidc/mappers/RegexRealmAndClientRoleClaimMapper.java new file mode 100644 index 0000000..dae5a23 --- /dev/null +++ b/module/src/main/java/com/github/lucafilipozzi/keycloak/broker/oidc/mappers/RegexRealmAndClientRoleClaimMapper.java @@ -0,0 +1,138 @@ +// Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENSE. + +package com.github.lucafilipozzi.keycloak.broker.oidc.mappers; + +import com.github.lucafilipozzi.keycloak.broker.util.RegexRealmAndClientRoleMapperUtil; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.jboss.logging.Logger; +import org.keycloak.broker.oidc.KeycloakOIDCIdentityProviderFactory; +import org.keycloak.broker.oidc.OIDCIdentityProviderFactory; +import org.keycloak.broker.oidc.mappers.AbstractClaimMapper; +import org.keycloak.broker.provider.BrokeredIdentityContext; +import org.keycloak.models.IdentityProviderMapperModel; +import org.keycloak.models.IdentityProviderSyncMode; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; +import org.keycloak.provider.ProviderConfigProperty; + +/** + * Map a claim to realm and client roles via regex. + */ +public class RegexRealmAndClientRoleClaimMapper extends AbstractClaimMapper { + + public static final String PROVIDER_ID = "lucafilipozzi-oidc-regex-claim-mapper"; + + public static final String OIDC_CLAIM_NAME = "oidc-claim-name"; + + protected static final String[] COMPATIBLE_PROVIDERS = { KeycloakOIDCIdentityProviderFactory.PROVIDER_ID, OIDCIdentityProviderFactory.PROVIDER_ID }; + + private static final Set IDENTITY_PROVIDER_SYNC_MODES = new HashSet<>(Arrays.asList(IdentityProviderSyncMode.values())); + + private static final Logger LOG = Logger.getLogger(RegexRealmAndClientRoleClaimMapper.class); + + private static final List configProperties = new ArrayList<>(); + + static { + ProviderConfigProperty oidcClaimNameConfigProperty = new ProviderConfigProperty(); + oidcClaimNameConfigProperty.setName(OIDC_CLAIM_NAME); + oidcClaimNameConfigProperty.setLabel("OIDC claim name"); + oidcClaimNameConfigProperty.setHelpText("name of OIDC claim to search"); + oidcClaimNameConfigProperty.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(oidcClaimNameConfigProperty); + + ProviderConfigProperty clientRolesAttributeNameConfigProperty = new ProviderConfigProperty(); + clientRolesAttributeNameConfigProperty.setName(RegexRealmAndClientRoleMapperUtil.CLIENT_ROLES_ATTRIBUTE_NAME); + clientRolesAttributeNameConfigProperty.setLabel("client roles attribute name"); + clientRolesAttributeNameConfigProperty.setHelpText("only evaluate client roles having an attribute with this name"); + clientRolesAttributeNameConfigProperty.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(clientRolesAttributeNameConfigProperty); + + ProviderConfigProperty clientRolesRegularExpressionConfigProperty = new ProviderConfigProperty(); + clientRolesRegularExpressionConfigProperty.setName(RegexRealmAndClientRoleMapperUtil.CLIENT_ROLES_REGULAR_EXPRESSION); + clientRolesRegularExpressionConfigProperty.setLabel("client roles regular expression"); + clientRolesRegularExpressionConfigProperty.setHelpText("regular expression to apply to the OIDC claim to extract client roles; must specify two named-capturing groups: client and role"); + clientRolesRegularExpressionConfigProperty.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(clientRolesRegularExpressionConfigProperty); + + ProviderConfigProperty realmRolesAttributeNameConfigProperty = new ProviderConfigProperty(); + realmRolesAttributeNameConfigProperty.setName(RegexRealmAndClientRoleMapperUtil.REALM_ROLES_ATTRIBUTE_NAME); + realmRolesAttributeNameConfigProperty.setLabel("realm roles attribute name"); + realmRolesAttributeNameConfigProperty.setHelpText("only evaluate realm roles having an attribute with this name"); + realmRolesAttributeNameConfigProperty.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(realmRolesAttributeNameConfigProperty); + + ProviderConfigProperty realmRolesRegularExpressionConfigProperty = new ProviderConfigProperty(); + realmRolesRegularExpressionConfigProperty.setName(RegexRealmAndClientRoleMapperUtil.REALM_ROLES_REGULAR_EXPRESSION); + realmRolesRegularExpressionConfigProperty.setLabel("realm roles regular expression"); + realmRolesRegularExpressionConfigProperty.setHelpText("regular expression to apply to the OIDC claim to extract realm roles; must specify one named-capturing groups: role"); + realmRolesRegularExpressionConfigProperty.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(realmRolesRegularExpressionConfigProperty); + } + + @Override + public String[] getCompatibleProviders() { + return COMPATIBLE_PROVIDERS; + } + + @Override + public List getConfigProperties() { + return configProperties; + } + + @Override + public String getDisplayCategory() { + return "Role Importer"; + } + + @Override + public String getDisplayType() { + return "Regex Realm and Client Role Importer"; + } + + @Override + public String getHelpText() { + return "implements regex realm and client role importer"; + } + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public boolean supportsSyncMode(IdentityProviderSyncMode syncMode) { + return IDENTITY_PROVIDER_SYNC_MODES.contains(syncMode); + } + + @Override + public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapper, BrokeredIdentityContext context) { + LOG.trace("import user"); + processUser(realm, user, mapper, context); + } + + @Override + public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapper, BrokeredIdentityContext context) { + LOG.trace("update user"); + processUser(realm, user, mapper, context); + } + + private void processUser(RealmModel realm, UserModel user, IdentityProviderMapperModel mapper, BrokeredIdentityContext context) { + LOG.trace("process user"); + String oidcClaimName = mapper.getConfig().getOrDefault(OIDC_CLAIM_NAME, ""); + Set assertedValues; + Object claimValue = getClaimValue(context, oidcClaimName); + if (claimValue instanceof List) { + assertedValues = ((List) claimValue).stream().map(String.class::cast).collect(Collectors.toSet()); + } else { + assertedValues = Collections.emptySet(); + } + RegexRealmAndClientRoleMapperUtil.processUser(realm, user, mapper, assertedValues); + } +} diff --git a/module/src/main/java/com/github/lucafilipozzi/keycloak/broker/saml/mappers/RegexRealmAndClientRoleAttributeMapper.java b/module/src/main/java/com/github/lucafilipozzi/keycloak/broker/saml/mappers/RegexRealmAndClientRoleAttributeMapper.java new file mode 100644 index 0000000..88b509b --- /dev/null +++ b/module/src/main/java/com/github/lucafilipozzi/keycloak/broker/saml/mappers/RegexRealmAndClientRoleAttributeMapper.java @@ -0,0 +1,138 @@ +// Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENSE. + +package com.github.lucafilipozzi.keycloak.broker.saml.mappers; + +import com.github.lucafilipozzi.keycloak.broker.util.RegexRealmAndClientRoleMapperUtil; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.jboss.logging.Logger; +import org.keycloak.broker.provider.AbstractIdentityProviderMapper; +import org.keycloak.broker.provider.BrokeredIdentityContext; +import org.keycloak.broker.saml.SAMLEndpoint; +import org.keycloak.broker.saml.SAMLIdentityProviderFactory; +import org.keycloak.dom.saml.v2.assertion.AssertionType; +import org.keycloak.models.IdentityProviderMapperModel; +import org.keycloak.models.IdentityProviderSyncMode; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; +import org.keycloak.provider.ProviderConfigProperty; + +/** + * Map an attribute to realm and client roles via regex. + */ +public class RegexRealmAndClientRoleAttributeMapper extends AbstractIdentityProviderMapper { + + public static final String PROVIDER_ID = "lucafilipozzi-saml-regex-attribute-mapper"; + + public static final String SAML_ATTRIBUTE_NAME = "saml-attribute-name"; + + protected static final String[] COMPATIBLE_PROVIDERS = {SAMLIdentityProviderFactory.PROVIDER_ID}; + + private static final Set IDENTITY_PROVIDER_SYNC_MODES = new HashSet<>(Arrays.asList(IdentityProviderSyncMode.values())); + + private static final Logger LOG = Logger.getLogger(RegexRealmAndClientRoleAttributeMapper.class); + + private static final List configProperties = new ArrayList<>(); + + static { + ProviderConfigProperty samlAttributeNameConfigProperty = new ProviderConfigProperty(); + samlAttributeNameConfigProperty.setName(SAML_ATTRIBUTE_NAME); + samlAttributeNameConfigProperty.setLabel("SAML attribute name"); + samlAttributeNameConfigProperty.setHelpText("name of SAML attribute to search (friendly or otherwise)"); + samlAttributeNameConfigProperty.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(samlAttributeNameConfigProperty); + + ProviderConfigProperty clientRolesAttributeNameConfigProperty = new ProviderConfigProperty(); + clientRolesAttributeNameConfigProperty.setName(RegexRealmAndClientRoleMapperUtil.CLIENT_ROLES_ATTRIBUTE_NAME); + clientRolesAttributeNameConfigProperty.setLabel("client roles attribute name"); + clientRolesAttributeNameConfigProperty.setHelpText("only evaluate client roles having an attribute with this name"); + clientRolesAttributeNameConfigProperty.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(clientRolesAttributeNameConfigProperty); + + ProviderConfigProperty clientRolesRegularExpressionConfigProperty = new ProviderConfigProperty(); + clientRolesRegularExpressionConfigProperty.setName(RegexRealmAndClientRoleMapperUtil.CLIENT_ROLES_REGULAR_EXPRESSION); + clientRolesRegularExpressionConfigProperty.setLabel("client roles regular expression"); + clientRolesRegularExpressionConfigProperty.setHelpText("regular expression to apply to the SAML attribute to extract client roles; must specify two named-capturing groups: client and role"); + clientRolesRegularExpressionConfigProperty.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(clientRolesRegularExpressionConfigProperty); + + ProviderConfigProperty realmRolesAttributeNameConfigProperty = new ProviderConfigProperty(); + realmRolesAttributeNameConfigProperty.setName(RegexRealmAndClientRoleMapperUtil.REALM_ROLES_ATTRIBUTE_NAME); + realmRolesAttributeNameConfigProperty.setLabel("realm roles attribute name"); + realmRolesAttributeNameConfigProperty.setHelpText("only evaluate realm roles having an attribute with this name"); + realmRolesAttributeNameConfigProperty.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(realmRolesAttributeNameConfigProperty); + + ProviderConfigProperty realmRolesRegularExpressionConfigProperty = new ProviderConfigProperty(); + realmRolesRegularExpressionConfigProperty.setName(RegexRealmAndClientRoleMapperUtil.REALM_ROLES_REGULAR_EXPRESSION); + realmRolesRegularExpressionConfigProperty.setLabel("realm roles regular expression"); + realmRolesRegularExpressionConfigProperty.setHelpText("regular expression to apply to the SAML attribute to extract realm roles; must specify one named-capturing group: role"); + realmRolesRegularExpressionConfigProperty.setType(ProviderConfigProperty.STRING_TYPE); + configProperties.add(realmRolesRegularExpressionConfigProperty); + } + + @Override + public String[] getCompatibleProviders() { + return COMPATIBLE_PROVIDERS; + } + + @Override + public List getConfigProperties() { + return configProperties; + } + + @Override + public String getDisplayCategory() { + return "Role Importer"; + } + + @Override + public String getDisplayType() { + return "Regex Realm and Client Role Importer"; + } + + @Override + public String getHelpText() { + return "implements regex realm and client role importer"; + } + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public boolean supportsSyncMode(IdentityProviderSyncMode syncMode) { + return IDENTITY_PROVIDER_SYNC_MODES.contains(syncMode); + } + + @Override + public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapper, BrokeredIdentityContext context) { + LOG.trace("import user"); + processUser(realm, user, mapper, context); + } + + @Override + public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapper, BrokeredIdentityContext context) { + LOG.trace("update user"); + processUser(realm, user, mapper, context); + } + + private void processUser(RealmModel realm, UserModel user, IdentityProviderMapperModel mapper, BrokeredIdentityContext context) { + LOG.trace("process user"); + String samlAttributeName = mapper.getConfig().getOrDefault(SAML_ATTRIBUTE_NAME, ""); + AssertionType assertion = (AssertionType) context.getContextData().get(SAMLEndpoint.SAML_ASSERTION); + Set assertedValues = assertion.getAttributeStatements().stream() + .flatMap(statement -> statement.getAttributes().stream()) + .filter(choice -> choice.getAttribute().getFriendlyName().equals(samlAttributeName) || choice.getAttribute().getName().equals(samlAttributeName)) + .flatMap(choice -> choice.getAttribute().getAttributeValue().stream()) + .map(Object::toString) + .collect(Collectors.toSet()); + RegexRealmAndClientRoleMapperUtil.processUser(realm, user, mapper, assertedValues); + } +} diff --git a/module/src/main/java/com/github/lucafilipozzi/keycloak/broker/util/RegexRealmAndClientRoleMapperUtil.java b/module/src/main/java/com/github/lucafilipozzi/keycloak/broker/util/RegexRealmAndClientRoleMapperUtil.java new file mode 100644 index 0000000..52caa8f --- /dev/null +++ b/module/src/main/java/com/github/lucafilipozzi/keycloak/broker/util/RegexRealmAndClientRoleMapperUtil.java @@ -0,0 +1,113 @@ +// Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENSE. + +package com.github.lucafilipozzi.keycloak.broker.util; + +import com.google.common.collect.Sets; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.jboss.logging.Logger; +import org.keycloak.models.ClientModel; +import org.keycloak.models.IdentityProviderMapperModel; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleModel; +import org.keycloak.models.UserModel; + +/** + * Utilities for adjusting user's realm and client role assignments. + */ +public final class RegexRealmAndClientRoleMapperUtil { + + public static final String CLIENT_ROLES_ATTRIBUTE_NAME = "client-roles-attribute-name"; + + public static final String CLIENT_ROLES_REGULAR_EXPRESSION = "client-roles-regular-expression"; + + public static final String REALM_ROLES_ATTRIBUTE_NAME = "realm-roles-attribute-name"; + + public static final String REALM_ROLES_REGULAR_EXPRESSION = "realm-roles-regular-expression"; + + private static final Logger LOG = Logger.getLogger(RegexRealmAndClientRoleMapperUtil.class); + + private RegexRealmAndClientRoleMapperUtil() { + throw new UnsupportedOperationException(); + } + + public static void processUser(RealmModel realm, UserModel user, IdentityProviderMapperModel mapper, Set assertedValues) { + LOG.trace("process user"); + + // adjust the user's client role assignments + String clientRolesRegularExpression = mapper.getConfig().getOrDefault(CLIENT_ROLES_REGULAR_EXPRESSION, ""); + String clientRolesAttributeName = mapper.getConfig().getOrDefault(CLIENT_ROLES_ATTRIBUTE_NAME, ""); + RegexRealmAndClientRoleMapperUtil.adjustUserClientRoleAssignments(realm, user, assertedValues, clientRolesRegularExpression, clientRolesAttributeName); + + // adjust the user's realm role assignments + String realmRolesRegularExpression = mapper.getConfig().getOrDefault(REALM_ROLES_REGULAR_EXPRESSION, ""); + String realmRolesAttributeName = mapper.getConfig().getOrDefault(REALM_ROLES_ATTRIBUTE_NAME, ""); + RegexRealmAndClientRoleMapperUtil.adjustUserRealmRoleAssignments(realm, user, assertedValues, realmRolesRegularExpression, realmRolesAttributeName); + } + + private static void adjustUserClientRoleAssignments(RealmModel realm, UserModel user, Set assertedValues, String regularExpression, String attributeName) { + LOG.trace("adjust user client role assignments"); + + Pattern pattern = Pattern.compile(regularExpression); + + // determine the client roles that the user should have + Set wantRoles = assertedValues.stream() + .map(pattern::matcher) + .filter(Matcher::matches) + .filter(matcher -> matcher.groupCount() == 2) + .filter(matcher -> matcher.group("client") != null) + .filter(matcher -> matcher.group("role") != null) + .flatMap(matcher -> + realm.getClientsStream() + .filter(client -> client.getClientId().equalsIgnoreCase(matcher.group("client"))) + .flatMap(ClientModel::getRolesStream) + .filter(clientRole -> clientRole.getAttributeStream(attributeName).findAny().isPresent()) + .filter(clientRole -> clientRole.getName().equalsIgnoreCase(matcher.group("role")))) + .collect(Collectors.toSet()); + + // determine the client roles that user does have + Set haveRoles = user.getRoleMappingsStream() + .filter(RoleModel::isClientRole) + .filter(clientRole -> clientRole.getAttributes().containsKey(attributeName)) + .collect(Collectors.toSet()); + + // assign the client roles that the user should have but doesn't + Sets.difference(wantRoles, haveRoles).forEach(user::grantRole); + + // un-assign the client roles that the user has but shouldn't + Sets.difference(haveRoles, wantRoles).forEach(user::deleteRoleMapping); + } + + private static void adjustUserRealmRoleAssignments(RealmModel realm, UserModel user, Set assertedValues, String regularExpression, String attributeName) { + LOG.trace("adjust user realm role assignments"); + + Pattern pattern = Pattern.compile(regularExpression); + + // determine the realm roles that the user should have + Set wantRoles = assertedValues.stream() + .map(pattern::matcher) + .filter(Matcher::matches) + .filter(matcher -> matcher.groupCount() == 1) + .filter(matcher -> matcher.group("role") != null) + .flatMap(matcher -> + realm.getRolesStream() + .filter(realmRole -> !realmRole.isClientRole()) + .filter(realmRole -> realmRole.getAttributeStream(attributeName).findAny().isPresent()) + .filter(realmRole -> realmRole.getName().equalsIgnoreCase(matcher.group("role")))) + .collect(Collectors.toSet()); + + // determine the realm roles that the user does have + Set haveRoles = user.getRoleMappingsStream() + .filter(realmRole -> !realmRole.isClientRole()) + .filter(realmRole -> realmRole.getAttributes().containsKey(attributeName)) + .collect(Collectors.toSet()); + + // assign the realm roles that the user should have but doesn't + Sets.difference(wantRoles, haveRoles).forEach(user::grantRole); + + // un-assign the realm roles that the user has but shouldn't + Sets.difference(haveRoles, wantRoles).forEach(user::deleteRoleMapping); + } +} diff --git a/module/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper b/module/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper new file mode 100644 index 0000000..8c66d3e --- /dev/null +++ b/module/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper @@ -0,0 +1,4 @@ +# Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENSE. + +com.github.lucafilipozzi.keycloak.broker.oidc.mappers.RegexRealmAndClientRoleClaimMapper +com.github.lucafilipozzi.keycloak.broker.saml.mappers.RegexRealmAndClientRoleAttributeMapper diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..1bcd323 --- /dev/null +++ b/pom.xml @@ -0,0 +1,342 @@ + + + + 4.0.0 + + + keycloak-parent + org.keycloak + 13.0.1 + + + com.github.lucafilipozzi + keycloak-regex-mapper + ${revision} + pom + parent + Keycloak Extensions Prototype + + + + Luca Filipozzi + + + + + GitHub Issues + https://github.com/lucafilipozzi/keycloak-regex-mapper/issues + + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + scm:git:https://github.com/lucafilipozzi/keycloak-regex-mapper + scm:git:git://github.com/lucafilipozzi/keycloak-regex-mapper + https://github.com/lucafilipozzi/keycloak-regex-mapper + + + + 1.8 + 1.8 + UTF-8 + 1.0.0-SNAPSHOT + 13.0.1 + + + + + + com.google.guava + guava + ${google.guava.version} + provided + + + com.github.lucafilipozzi + keycloak-regex-mapper-module + ${revision} + + + org.jboss.logging + jboss-logging + ${jboss.logging.version} + provided + + + org.keycloak + keycloak-common + ${keycloak.version} + provided + + + org.keycloak + keycloak-core + ${keycloak.version} + provided + + + org.keycloak + keycloak-saml-core-public + ${keycloak.version} + provided + + + org.keycloak + keycloak-server-spi + ${keycloak.version} + provided + + + org.keycloak + keycloak-server-spi-private + ${keycloak.version} + provided + + + org.keycloak + keycloak-services + ${keycloak.version} + provided + + + + + + module + bundle + + + + + + + + org.apache.maven.plugins + maven-clean-plugin + 3.1.0 + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M3 + + + + + 1.8 + + + 3.6.0 + + + true + true + true + + + + ${project.groupId}:* + + + + + org.apache.maven.plugins:maven-surefire-plugin + org.apache.maven.plugins:maven-failsafe-plugin + + + + + + + + + validate + + enforce + + + + + + org.codehaus.mojo + extra-enforcer-rules + 1.3 + + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.4 + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.2.0 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1-jboss-2 + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.0.0-M5 + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + org.apache.maven.plugins + maven-ear-plugin + 3.2.0 + + + org.codehaus.plexus + plexus-archiver + 4.2.5 + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.2 + + + com.puppycrawl.tools + checkstyle + 8.45.1 + + + + google_checks.xml + true + ${project.build.sourceEncoding} + true + .checkstyle-suppressions.xml + + + + verify + + check + + + + + + org.owasp + dependency-check-maven + 6.2.2 + + + verify + + check + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.8.1 + + false + false + false + false + false + + + + verify + + display-dependency-updates + display-plugin-updates + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.2.0 + + + verify + + analyze + + + + + + org.basepom.maven + duplicate-finder-maven-plugin + 1.5.0 + + + verify + + check + + + + + + + + org.apache.maven.plugins + maven-install-plugin + 3.0.0-M1 + + + + + org.apache.maven.plugins + maven-site-plugin + 3.9.1 + + + + + org.apache.maven.plugins + maven-deploy-plugin + 3.0.0-M1 + + + + +