Details
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
index 33ae2d5..428d94c 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
@@ -132,7 +132,7 @@ public class UserInfoEndpoint {
ClientModel clientModel = realm.getClientByClientId(token.getIssuedFor());
UserModel userModel = userSession.getUser();
AccessToken userInfo = new AccessToken();
- tokenManager.transformAccessToken(session, userInfo, realm, clientModel, userModel, userSession, clientSession);
+ tokenManager.transformUserInfoAccessToken(session, userInfo, realm, clientModel, userModel, userSession, clientSession);
event
.detail(Details.USERNAME, userModel.getUsername())
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java
index 1cc87d9..f452261 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java
@@ -18,6 +18,7 @@
package org.keycloak.protocol.oidc.mappers;
import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.protocol.ProtocolMapper;
import org.keycloak.protocol.ProtocolMapperUtils;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.provider.ProviderConfigProperty;
@@ -48,6 +49,10 @@ public class OIDCAttributeMapperHelper {
public static final String INCLUDE_IN_ID_TOKEN_LABEL = "includeInIdToken.label";
public static final String INCLUDE_IN_ID_TOKEN_HELP_TEXT = "includeInIdToken.tooltip";
+ public static final String INCLUDE_IN_USERINFO = "userinfo.token.claim";
+ public static final String INCLUDE_IN_USERINFO_LABEL = "includeInUserInfo.label";
+ public static final String INCLUDE_IN_USERINFO_HELP_TEXT = "includeInUserInfo.tooltip";
+
public static Object mapAttributeValue(ProtocolMapperModel mappingModel, Object attributeValue) {
if (attributeValue == null) return null;
@@ -115,10 +120,19 @@ public class OIDCAttributeMapperHelper {
}
public static ProtocolMapperModel createClaimMapper(String name,
+ String userAttribute,
+ String tokenClaimName, String claimType,
+ boolean consentRequired, String consentText,
+ boolean accessToken, boolean idToken,
+ String mapperId) {
+ return createClaimMapper(name, userAttribute,tokenClaimName, claimType, consentRequired, consentText, accessToken, idToken, false, mapperId);
+ }
+
+ public static ProtocolMapperModel createClaimMapper(String name,
String userAttribute,
String tokenClaimName, String claimType,
boolean consentRequired, String consentText,
- boolean accessToken, boolean idToken,
+ boolean accessToken, boolean idToken, boolean userinfo,
String mapperId) {
ProtocolMapperModel mapper = new ProtocolMapperModel();
mapper.setName(name);
@@ -132,6 +146,7 @@ public class OIDCAttributeMapperHelper {
config.put(JSON_TYPE, claimType);
if (accessToken) config.put(INCLUDE_IN_ACCESS_TOKEN, "true");
if (idToken) config.put(INCLUDE_IN_ID_TOKEN, "true");
+ if (userinfo) config.put(INCLUDE_IN_USERINFO, "true");
mapper.setConfig(config);
return mapper;
}
@@ -144,11 +159,14 @@ public class OIDCAttributeMapperHelper {
return "true".equals(mappingModel.getConfig().get(INCLUDE_IN_ACCESS_TOKEN));
}
-
public static boolean isMultivalued(ProtocolMapperModel mappingModel) {
return "true".equals(mappingModel.getConfig().get(ProtocolMapperUtils.MULTIVALUED));
}
+ public static boolean includeInUserInfo(ProtocolMapperModel mappingModel){
+ return "true".equals(mappingModel.getConfig().get(INCLUDE_IN_USERINFO));
+ }
+
public static void addAttributeConfig(List<ProviderConfigProperty> configProperties) {
ProviderConfigProperty property;
property = new ProviderConfigProperty();
@@ -183,5 +201,12 @@ public class OIDCAttributeMapperHelper {
property.setDefaultValue("true");
property.setHelpText(INCLUDE_IN_ACCESS_TOKEN_HELP_TEXT);
configProperties.add(property);
+ property = new ProviderConfigProperty();
+ property.setName(INCLUDE_IN_USERINFO);
+ property.setLabel(INCLUDE_IN_USERINFO_LABEL);
+ property.setType(ProviderConfigProperty.BOOLEAN_TYPE);
+ property.setDefaultValue("false");
+ property.setHelpText(INCLUDE_IN_USERINFO_HELP_TEXT);
+ configProperties.add(property);
}
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserAttributeMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserAttributeMapper.java
index 558d3a7..56e7a48 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserAttributeMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserAttributeMapper.java
@@ -39,7 +39,7 @@ import java.util.List;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
-public class UserAttributeMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper {
+public class UserAttributeMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper {
private static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
@@ -113,11 +113,22 @@ public class UserAttributeMapper extends AbstractOIDCProtocolMapper implements O
return token;
}
+ @Override
+ public AccessToken transformUserInfoToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession) {
+
+ if (!OIDCAttributeMapperHelper.includeInUserInfo(mappingModel)) {
+ return token;
+ }
+
+ setClaim(token, mappingModel, userSession);
+ return token;
+ }
+
public static ProtocolMapperModel createClaimMapper(String name,
- String userAttribute,
- String tokenClaimName, String claimType,
- boolean consentRequired, String consentText,
- boolean accessToken, boolean idToken, boolean multivalued) {
+ String userAttribute,
+ String tokenClaimName, String claimType,
+ boolean consentRequired, String consentText,
+ boolean accessToken, boolean idToken, boolean multivalued) {
ProtocolMapperModel mapper = OIDCAttributeMapperHelper.createClaimMapper(name, userAttribute,
tokenClaimName, claimType,
consentRequired, consentText,
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserInfoTokenMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserInfoTokenMapper.java
new file mode 100644
index 0000000..a93e62b
--- /dev/null
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserInfoTokenMapper.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.protocol.oidc.mappers;
+
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.representations.AccessToken;
+
+/**
+ * @author <a href="mailto:thomas.darimont@gmail.com">Thomas Darimont</a>
+ */
+public interface UserInfoTokenMapper {
+
+ AccessToken transformUserInfoToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session,
+ UserSessionModel userSession, ClientSessionModel clientSession);
+}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
index bbd41c0..a14c669 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
@@ -44,6 +44,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.protocol.ProtocolMapper;
import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
import org.keycloak.protocol.oidc.mappers.OIDCIDTokenMapper;
+import org.keycloak.protocol.oidc.mappers.UserInfoTokenMapper;
import org.keycloak.protocol.oidc.utils.OIDCResponseType;
import org.keycloak.protocol.oidc.utils.WebOriginsUtils;
import org.keycloak.representations.AccessToken;
@@ -492,6 +493,27 @@ public class TokenManager {
}
return token;
}
+
+ public AccessToken transformUserInfoAccessToken(KeycloakSession session, AccessToken token, RealmModel realm, ClientModel client, UserModel user,
+ UserSessionModel userSession, ClientSessionModel clientSession) {
+ Set<ProtocolMapperModel> mappings = new ClientSessionCode(realm, clientSession).getRequestedProtocolMappers();
+ KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
+ for (ProtocolMapperModel mapping : mappings) {
+
+ ProtocolMapper mapper = (ProtocolMapper)sessionFactory.getProviderFactory(ProtocolMapper.class, mapping.getProtocolMapper());
+ if (mapper == null || !(mapper instanceof OIDCAccessTokenMapper)) continue;
+
+ if(mapper instanceof UserInfoTokenMapper){
+ token = ((UserInfoTokenMapper)mapper).transformUserInfoToken(token, mapping, session, userSession, clientSession);
+ continue;
+ }
+
+ token = ((OIDCAccessTokenMapper)mapper).transformAccessToken(token, mapping, session, userSession, clientSession);
+
+ }
+ return token;
+ }
+
public void transformIDToken(KeycloakSession session, IDToken token, RealmModel realm, ClientModel client, UserModel user,
UserSessionModel userSession, ClientSessionModel clientSession) {
Set<ProtocolMapperModel> mappings = new ClientSessionCode(realm, clientSession).getRequestedProtocolMappers();
diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
index 77f4ae7..a057a25 100644
--- a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
+++ b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
@@ -156,6 +156,8 @@ includeInIdToken.label=Add to ID token
includeInIdToken.tooltip=Should the claim be added to the ID token?
includeInAccessToken.label=Add to access token
includeInAccessToken.tooltip=Should the claim be added to the access token?
+includeInUserInfo.label=Add to userinfo
+includeInUserInfo.tooltip=Should the claim be added to the userinfo?
usermodel.clientRoleMapping.clientId.label=Client ID
usermodel.clientRoleMapping.clientId.tooltip=Client ID for role mappings
usermodel.clientRoleMapping.rolePrefix.label=Client Role prefix