Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9151d2a
commit 44787d8
Showing
11 changed files
with
285 additions
and
102 deletions.
There are no files selected for viewing
110 changes: 110 additions & 0 deletions
110
broker/core/src/main/java/org/keycloak/broker/provider/HardcodedRoleMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package org.keycloak.broker.provider; | ||
|
||
import org.keycloak.broker.provider.AbstractIdentityProviderMapper; | ||
import org.keycloak.broker.provider.BrokeredIdentityContext; | ||
import org.keycloak.broker.provider.IdentityBrokerException; | ||
import org.keycloak.models.ClientModel; | ||
import org.keycloak.models.IdentityProviderMapperModel; | ||
import org.keycloak.models.KeycloakSession; | ||
import org.keycloak.models.RealmModel; | ||
import org.keycloak.models.RoleModel; | ||
import org.keycloak.models.UserModel; | ||
import org.keycloak.provider.ProviderConfigProperty; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> | ||
* @version $Revision: 1 $ | ||
*/ | ||
public class HardcodedRoleMapper extends AbstractIdentityProviderMapper { | ||
public static final String ROLE = "role"; | ||
protected static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>(); | ||
|
||
static { | ||
ProviderConfigProperty property; | ||
property = new ProviderConfigProperty(); | ||
property.setName(ROLE); | ||
property.setLabel("Role"); | ||
property.setHelpText("Role to grant to user. To reference an application role the syntax is appname.approle, i.e. myapp.myrole"); | ||
property.setType(ProviderConfigProperty.STRING_TYPE); | ||
configProperties.add(property); | ||
} | ||
|
||
|
||
|
||
public static String[] parseRole(String role) { | ||
int scopeIndex = role.indexOf('.'); | ||
if (scopeIndex > -1) { | ||
String appName = role.substring(0, scopeIndex); | ||
role = role.substring(scopeIndex + 1); | ||
String[] rtn = {appName, role}; | ||
return rtn; | ||
} else { | ||
String[] rtn = {null, role}; | ||
return rtn; | ||
|
||
} | ||
} | ||
|
||
public static RoleModel getRoleFromString(RealmModel realm, String roleName) { | ||
String[] parsedRole = parseRole(roleName); | ||
RoleModel role = null; | ||
if (parsedRole[0] == null) { | ||
role = realm.getRole(parsedRole[1]); | ||
} else { | ||
ClientModel client = realm.getClientByClientId(parsedRole[0]); | ||
role = client.getRole(parsedRole[1]); | ||
} | ||
return role; | ||
} | ||
|
||
@Override | ||
public List<ProviderConfigProperty> getConfigProperties() { | ||
return configProperties; | ||
} | ||
|
||
@Override | ||
public String getDisplayCategory() { | ||
return "Role Importer"; | ||
} | ||
|
||
@Override | ||
public String getDisplayType() { | ||
return "Hardcoded Role"; | ||
} | ||
|
||
public static final String[] COMPATIBLE_PROVIDERS = {ANY_PROVIDER}; | ||
|
||
|
||
public static final String PROVIDER_ID = "oidc-hardcoded-role-idp-mapper"; | ||
|
||
@Override | ||
public String getId() { | ||
return PROVIDER_ID; | ||
} | ||
|
||
@Override | ||
public String[] getCompatibleProviders() { | ||
return COMPATIBLE_PROVIDERS; | ||
} | ||
|
||
@Override | ||
public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { | ||
String roleName = mapperModel.getConfig().get(ROLE); | ||
RoleModel role = getRoleFromString(realm, roleName); | ||
if (role == null) throw new IdentityBrokerException("Unable to find role: " + roleName); | ||
user.grantRole(role); | ||
} | ||
|
||
@Override | ||
public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { | ||
|
||
} | ||
|
||
@Override | ||
public String getHelpText() { | ||
return "When user is imported from provider, hardcode a role mapping for it."; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
.../src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
org.keycloak.broker.provider.HardcodedRoleMapper |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 118 additions & 0 deletions
118
...oidc/src/main/java/org/keycloak/broker/oidc/mappers/ExternalKeycloakRoleToRoleMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package org.keycloak.broker.oidc.mappers; | ||
|
||
import org.keycloak.broker.oidc.KeycloakOIDCIdentityProvider; | ||
import org.keycloak.broker.oidc.KeycloakOIDCIdentityProviderFactory; | ||
import org.keycloak.broker.oidc.OIDCIdentityProviderFactory; | ||
import org.keycloak.broker.provider.BrokeredIdentityContext; | ||
import org.keycloak.broker.provider.HardcodedRoleMapper; | ||
import org.keycloak.broker.provider.IdentityBrokerException; | ||
import org.keycloak.models.IdentityProviderMapperModel; | ||
import org.keycloak.models.KeycloakSession; | ||
import org.keycloak.models.RealmModel; | ||
import org.keycloak.models.RoleModel; | ||
import org.keycloak.models.UserModel; | ||
import org.keycloak.provider.ProviderConfigProperty; | ||
import org.keycloak.representations.JsonWebToken; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> | ||
* @version $Revision: 1 $ | ||
*/ | ||
public class ExternalKeycloakRoleToRoleMapper extends AbstractClaimMapper { | ||
|
||
public static final String[] COMPATIBLE_PROVIDERS = {KeycloakOIDCIdentityProviderFactory.PROVIDER_ID}; | ||
|
||
private static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>(); | ||
private static final String EXTERNAL_ROLE = "external.role"; | ||
|
||
static { | ||
ProviderConfigProperty property; | ||
ProviderConfigProperty property1; | ||
property1 = new ProviderConfigProperty(); | ||
property1.setName(EXTERNAL_ROLE); | ||
property1.setLabel("External role"); | ||
property1.setHelpText("External role to check for. To reference an application role the syntax is appname.approle, i.e. myapp.myrole."); | ||
property1.setType(ProviderConfigProperty.STRING_TYPE); | ||
configProperties.add(property1); | ||
property = new ProviderConfigProperty(); | ||
property.setName(HardcodedRoleMapper.ROLE); | ||
property.setLabel("Role"); | ||
property.setHelpText("Role to grant to user if external role is present. To reference an application role the syntax is appname.approle, i.e. myapp.myrole"); | ||
property.setType(ProviderConfigProperty.STRING_TYPE); | ||
configProperties.add(property); | ||
} | ||
|
||
public static final String PROVIDER_ID = "keycloak-oidc-role-to-role-idp-mapper"; | ||
|
||
|
||
@Override | ||
public List<ProviderConfigProperty> getConfigProperties() { | ||
return configProperties; | ||
} | ||
|
||
@Override | ||
public String getId() { | ||
return PROVIDER_ID; | ||
} | ||
|
||
@Override | ||
public String[] getCompatibleProviders() { | ||
return COMPATIBLE_PROVIDERS; | ||
} | ||
|
||
@Override | ||
public String getDisplayCategory() { | ||
return "Role Importer"; | ||
} | ||
|
||
@Override | ||
public String getDisplayType() { | ||
return "External Role to Role"; | ||
} | ||
|
||
@Override | ||
public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { | ||
RoleModel role = hasRole(realm, mapperModel, context); | ||
if (role != null) { | ||
user.grantRole(role); | ||
} | ||
} | ||
|
||
private RoleModel hasRole(RealmModel realm,IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { | ||
JsonWebToken token = (JsonWebToken)context.getContextData().get(KeycloakOIDCIdentityProvider.VALIDATED_ACCESS_TOKEN); | ||
//if (token == null) return; | ||
String roleName = mapperModel.getConfig().get(HardcodedRoleMapper.ROLE); | ||
String[] parseRole = HardcodedRoleMapper.parseRole(mapperModel.getConfig().get(EXTERNAL_ROLE)); | ||
String externalRoleName = parseRole[1]; | ||
String claimName = null; | ||
if (parseRole[0] == null) { | ||
claimName = "realm_access.roles"; | ||
} else { | ||
claimName = "resource_access." + parseRole[0] + ".roles"; | ||
} | ||
Object claim = getClaimValue(token, claimName); | ||
if (valueEquals(externalRoleName, claim)) { | ||
RoleModel role = HardcodedRoleMapper.getRoleFromString(realm, roleName); | ||
if (role == null) throw new IdentityBrokerException("Unable to find role: " + roleName); | ||
return role; | ||
} | ||
return null; | ||
} | ||
|
||
@Override | ||
public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { | ||
RoleModel role = hasRole(realm, mapperModel, context); | ||
if (role == null) { | ||
user.deleteRoleMapping(role); | ||
} | ||
} | ||
|
||
@Override | ||
public String getHelpText() { | ||
return "Looks for an external role in a keycloak access token. If external role exists, grant the user the specified realm or application role."; | ||
} | ||
|
||
} |
3 changes: 2 additions & 1 deletion
3
.../src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
org.keycloak.broker.oidc.mappers.RoleMapper | ||
org.keycloak.broker.oidc.mappers.ClaimToRoleMapper | ||
org.keycloak.broker.oidc.mappers.ExternalKeycloakRoleToRoleMapper | ||
org.keycloak.broker.oidc.mappers.UserAttributeMapper |
Oops, something went wrong.