add code
This commit is contained in:
parent
3e5aa8f6f6
commit
58ac3c5921
9 changed files with 886 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,5 +1,8 @@
|
||||||
# Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENCE.
|
# Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENCE.
|
||||||
|
|
||||||
|
# direnv
|
||||||
|
.envrc
|
||||||
|
|
||||||
# idea
|
# idea
|
||||||
.idea/
|
.idea/
|
||||||
*.iml
|
*.iml
|
||||||
|
|
47
bundle/pom.xml
Normal file
47
bundle/pom.xml
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENSE. -->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.github.lucafilipozzi</groupId>
|
||||||
|
<artifactId>keycloak-regex-mapper</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>keycloak-regex-mapper-bundle</artifactId>
|
||||||
|
<packaging>ear</packaging>
|
||||||
|
<name>bundle</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.parent.groupId}</groupId>
|
||||||
|
<artifactId>${project.parent.artifactId}-module</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<!-- drop '-bundle' from finalName of the ear-->
|
||||||
|
<finalName>${project.parent.artifactId}-${revision}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-ear-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<displayName>${project.parent.artifactId}</displayName>
|
||||||
|
<description>${project.parent.description}</description>
|
||||||
|
<modules>
|
||||||
|
<jarModule>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>${project.parent.artifactId}-module</artifactId>
|
||||||
|
<!-- drop '-module' from finalName of the jar within the ear -->
|
||||||
|
<bundleFileName>${project.parent.groupId}-${project.parent.artifactId}-${revision}.jar</bundleFileName>
|
||||||
|
<includeInApplicationXml>true</includeInApplicationXml>
|
||||||
|
</jarModule>
|
||||||
|
</modules>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENSE. -->
|
||||||
|
<jboss-deployment-structure>
|
||||||
|
<deployment>
|
||||||
|
<dependencies>
|
||||||
|
<module name="com.google.guava" export="true"/>
|
||||||
|
<module name="org.jboss.logging" export="true"/>
|
||||||
|
<module name="org.keycloak.keycloak-common" export="true"/>
|
||||||
|
<module name="org.keycloak.keycloak-core" export="true"/>
|
||||||
|
<module name="org.keycloak.keycloak-saml-core-public" export="true"/>
|
||||||
|
<module name="org.keycloak.keycloak-server-spi" export="true"/>
|
||||||
|
<module name="org.keycloak.keycloak-server-spi-private" export="true"/>
|
||||||
|
<module name="org.keycloak.keycloak-services" export="true"/>
|
||||||
|
</dependencies>
|
||||||
|
</deployment>
|
||||||
|
</jboss-deployment-structure>
|
85
module/pom.xml
Normal file
85
module/pom.xml
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENSE. -->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.github.lucafilipozzi</groupId>
|
||||||
|
<artifactId>keycloak-regex-mapper</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>keycloak-regex-mapper-module</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>module</name>
|
||||||
|
|
||||||
|
<!-- IMPORTANT: don't forget to update jboss-deployment-structure.xml -->
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.logging</groupId>
|
||||||
|
<artifactId>jboss-logging</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-saml-core-public</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-server-spi</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-server-spi-private</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-services</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- verify -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.owasp</groupId>
|
||||||
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>versions-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<ignoredUnusedDeclaredDependencies>
|
||||||
|
<ignoredUnusedDeclaredDependency>org.keycloak:keycloak-common</ignoredUnusedDeclaredDependency>
|
||||||
|
<ignoredUnusedDeclaredDependency>org.keycloak:keycloak-core</ignoredUnusedDeclaredDependency>
|
||||||
|
<ignoredUnusedDeclaredDependency>org.keycloak:keycloak-server-spi</ignoredUnusedDeclaredDependency>
|
||||||
|
</ignoredUnusedDeclaredDependencies>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.basepom.maven</groupId>
|
||||||
|
<artifactId>duplicate-finder-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -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<IdentityProviderSyncMode> IDENTITY_PROVIDER_SYNC_MODES = new HashSet<>(Arrays.asList(IdentityProviderSyncMode.values()));
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(RegexRealmAndClientRoleClaimMapper.class);
|
||||||
|
|
||||||
|
private static final List<ProviderConfigProperty> 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<ProviderConfigProperty> 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<String> 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<IdentityProviderSyncMode> IDENTITY_PROVIDER_SYNC_MODES = new HashSet<>(Arrays.asList(IdentityProviderSyncMode.values()));
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(RegexRealmAndClientRoleAttributeMapper.class);
|
||||||
|
|
||||||
|
private static final List<ProviderConfigProperty> 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<ProviderConfigProperty> 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<String> 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<String> 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<String> 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<RoleModel> 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<RoleModel> 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<String> 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<RoleModel> 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<RoleModel> 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
342
pom.xml
Normal file
342
pom.xml
Normal file
|
@ -0,0 +1,342 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENSE. -->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<artifactId>keycloak-parent</artifactId>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<version>13.0.1</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.github.lucafilipozzi</groupId>
|
||||||
|
<artifactId>keycloak-regex-mapper</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<name>parent</name>
|
||||||
|
<description>Keycloak Extensions Prototype</description>
|
||||||
|
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<name>Luca Filipozzi</name>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
|
||||||
|
<issueManagement>
|
||||||
|
<system>GitHub Issues</system>
|
||||||
|
<url>https://github.com/lucafilipozzi/keycloak-regex-mapper/issues</url>
|
||||||
|
</issueManagement>
|
||||||
|
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>Apache License, Version 2.0</name>
|
||||||
|
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||||
|
<distribution>repo</distribution>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
|
||||||
|
<scm>
|
||||||
|
<connection>scm:git:https://github.com/lucafilipozzi/keycloak-regex-mapper</connection>
|
||||||
|
<developerConnection>scm:git:git://github.com/lucafilipozzi/keycloak-regex-mapper</developerConnection>
|
||||||
|
<url>https://github.com/lucafilipozzi/keycloak-regex-mapper</url>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<revision>1.0.0-SNAPSHOT</revision>
|
||||||
|
<keycloak.version>13.0.1</keycloak.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${google.guava.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.lucafilipozzi</groupId>
|
||||||
|
<artifactId>keycloak-regex-mapper-module</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.logging</groupId>
|
||||||
|
<artifactId>jboss-logging</artifactId>
|
||||||
|
<version>${jboss.logging.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-common</artifactId>
|
||||||
|
<version>${keycloak.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-core</artifactId>
|
||||||
|
<version>${keycloak.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-saml-core-public</artifactId>
|
||||||
|
<version>${keycloak.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-server-spi</artifactId>
|
||||||
|
<version>${keycloak.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-server-spi-private</artifactId>
|
||||||
|
<version>${keycloak.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-services</artifactId>
|
||||||
|
<version>${keycloak.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>module</module>
|
||||||
|
<module>bundle</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<!-- clean -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- validate -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
|
<version>3.0.0-M3</version>
|
||||||
|
<configuration>
|
||||||
|
<rules>
|
||||||
|
<!-- org.apache.maven.plugins:maven-enforcer-plugin -->
|
||||||
|
<requireJavaVersion>
|
||||||
|
<version>1.8</version>
|
||||||
|
</requireJavaVersion>
|
||||||
|
<requireMavenVersion>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
</requireMavenVersion>
|
||||||
|
<requirePluginVersions>
|
||||||
|
<banLatest>true</banLatest>
|
||||||
|
<banRelease>true</banRelease>
|
||||||
|
<banSnapshots>true</banSnapshots>
|
||||||
|
</requirePluginVersions>
|
||||||
|
<requireReleaseDeps>
|
||||||
|
<excludes>
|
||||||
|
<exclude>${project.groupId}:*</exclude>
|
||||||
|
</excludes>
|
||||||
|
</requireReleaseDeps>
|
||||||
|
<requireSameVersions>
|
||||||
|
<buildPlugins>
|
||||||
|
<plugin>org.apache.maven.plugins:maven-surefire-plugin</plugin>
|
||||||
|
<plugin>org.apache.maven.plugins:maven-failsafe-plugin</plugin>
|
||||||
|
</buildPlugins>
|
||||||
|
</requireSameVersions>
|
||||||
|
<!-- org.codehaus.mojo:extra-enforcer-rules -->
|
||||||
|
<banCircularDependencies/>
|
||||||
|
</rules>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>enforce</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>extra-enforcer-rules</artifactId>
|
||||||
|
<version>1.3</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>buildnumber-maven-plugin</artifactId>
|
||||||
|
<version>1.4</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- compile -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1-jboss-2</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- test -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.0.0-M5</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
<version>3.0.0-M5</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- package -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-ear-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.plexus</groupId>
|
||||||
|
<artifactId>plexus-archiver</artifactId>
|
||||||
|
<version>4.2.5</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<version>3.2.1</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- verify -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
<version>3.1.2</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.puppycrawl.tools</groupId>
|
||||||
|
<artifactId>checkstyle</artifactId>
|
||||||
|
<version>8.45.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<configuration>
|
||||||
|
<configLocation>google_checks.xml</configLocation>
|
||||||
|
<consoleOutput>true</consoleOutput>
|
||||||
|
<encoding>${project.build.sourceEncoding}</encoding>
|
||||||
|
<failsOnError>true</failsOnError>
|
||||||
|
<suppressionsLocation>.checkstyle-suppressions.xml</suppressionsLocation>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.owasp</groupId>
|
||||||
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
|
<version>6.2.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>versions-maven-plugin</artifactId>
|
||||||
|
<version>2.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<allowMajorUpdates>false</allowMajorUpdates>
|
||||||
|
<allowMinorUpdates>false</allowMinorUpdates>
|
||||||
|
<allowIncrementalUpdates>false</allowIncrementalUpdates>
|
||||||
|
<allowSnapshots>false</allowSnapshots>
|
||||||
|
<processDependencyManagement>false</processDependencyManagement>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>display-dependency-updates</goal>
|
||||||
|
<goal>display-plugin-updates</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>analyze</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.basepom.maven</groupId>
|
||||||
|
<artifactId>duplicate-finder-maven-plugin</artifactId>
|
||||||
|
<version>1.5.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- install -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
|
<version>3.0.0-M1</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- site -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<version>3.9.1</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- deploy -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.0.0-M1</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
Loading…
Add table
Reference in a new issue