update for KEYCLOAK-6884 KEYCLOAK-3454 KEYCLOAK-8298
|  |  |  | 
|---|
|  |  |  | for (ProtocolMapperModel mapping : mappings) { | 
|---|
|  |  |  | ProtocolMapper mapper = (ProtocolMapper) sessionFactory.getProviderFactory(ProtocolMapper.class, mapping.getProtocolMapper()); | 
|---|
|  |  |  | if (mapper instanceof CASAttributeMapper) { | 
|---|
|  |  |  | ((CASAttributeMapper) mapper).setAttribute(attributes, mapping, userSession); | 
|---|
|  |  |  | ((CASAttributeMapper) mapper).setAttribute(attributes, mapping, userSession, session, clientSessionCtx); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | package org.keycloak.protocol.cas.mappers; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.keycloak.models.*; | 
|---|
|  |  |  | import org.keycloak.models.utils.RoleUtils; | 
|---|
|  |  |  | import org.keycloak.models.ProtocolMapperModel; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import java.util.Map; | 
|---|
|  |  |  | import java.util.Set; | 
|---|
|  |  |  | import java.util.function.Predicate; | 
|---|
|  |  |  | import java.util.stream.Collectors; | 
|---|
|  |  |  | import java.util.stream.Stream; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * Base class for mapping of user role mappings to an ID and Access Token claim. | 
|---|
|  |  |  | 
|---|
|  |  |  | abstract class AbstractUserRoleMappingMapper extends AbstractCASProtocolMapper { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * Returns a stream with roles that come from: | 
|---|
|  |  |  | * <ul> | 
|---|
|  |  |  | * <li>Direct assignment of the role to the user</li> | 
|---|
|  |  |  | * <li>Direct assignment of the role to any group of the user or any of its parent group</li> | 
|---|
|  |  |  | * <li>Composite roles are expanded recursively, the composite role itself is also contained in the returned stream</li> | 
|---|
|  |  |  | * </ul> | 
|---|
|  |  |  | * @param user User to enumerate the roles for | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public Stream<RoleModel> getAllUserRolesStream(UserModel user) { | 
|---|
|  |  |  | return Stream.concat( | 
|---|
|  |  |  | user.getRoleMappings().stream(), | 
|---|
|  |  |  | user.getGroups().stream() | 
|---|
|  |  |  | .flatMap(this::groupAndItsParentsStream) | 
|---|
|  |  |  | .flatMap(g -> g.getRoleMappings().stream())) | 
|---|
|  |  |  | .flatMap(RoleUtils::expandCompositeRolesStream); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * Returns stream of the given group and its parents (recursively). | 
|---|
|  |  |  | * @param group | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private Stream<GroupModel> groupAndItsParentsStream(GroupModel group) { | 
|---|
|  |  |  | Stream.Builder<GroupModel> sb = Stream.builder(); | 
|---|
|  |  |  | while (group != null) { | 
|---|
|  |  |  | sb.add(group); | 
|---|
|  |  |  | group = group.getParent(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return sb.build(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * Retrieves all roles of the current user based on direct roles set to the user, its groups and their parent groups. | 
|---|
|  |  |  | * Then it recursively expands all composite roles, and restricts according to the given predicate {@code restriction}. | 
|---|
|  |  |  | * If the current client sessions is restricted (i.e. no client found in active user session has full scope allowed), | 
|---|
|  |  |  | * the final list of roles is also restricted by the client scope. Finally, the list is mapped to the token into | 
|---|
|  |  |  | * a claim. | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | protected void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession, | 
|---|
|  |  |  | Predicate<RoleModel> restriction, String prefix) { | 
|---|
|  |  |  | String rolePrefix = prefix == null ? "" : prefix; | 
|---|
|  |  |  | UserModel user = userSession.getUser(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // get a set of all realm roles assigned to the user or its group | 
|---|
|  |  |  | Stream<RoleModel> clientUserRoles = getAllUserRolesStream(user).filter(restriction); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | boolean dontLimitScope = userSession.getAuthenticatedClientSessions().values().stream().anyMatch(cs -> cs.getClient().isFullScopeAllowed()); | 
|---|
|  |  |  | if (! dontLimitScope) { | 
|---|
|  |  |  | Set<RoleModel> clientRoles = userSession.getAuthenticatedClientSessions().values().stream() | 
|---|
|  |  |  | .flatMap(cs -> cs.getClient().getScopeMappings().stream()) | 
|---|
|  |  |  | protected void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, Set<String> rolesToAdd, | 
|---|
|  |  |  | String prefix) { | 
|---|
|  |  |  | Set<String> realmRoleNames; | 
|---|
|  |  |  | if (prefix != null && !prefix.isEmpty()) { | 
|---|
|  |  |  | realmRoleNames = rolesToAdd.stream() | 
|---|
|  |  |  | .map(roleName -> prefix + roleName) | 
|---|
|  |  |  | .collect(Collectors.toSet()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | clientUserRoles = clientUserRoles.filter(clientRoles::contains); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | realmRoleNames = rolesToAdd; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Set<String> realmRoleNames = clientUserRoles | 
|---|
|  |  |  | .map(m -> rolePrefix + m.getName()) | 
|---|
|  |  |  | .collect(Collectors.toSet()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | setPlainAttribute(attributes, mappingModel, realmRoleNames); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | package org.keycloak.protocol.cas.mappers; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.keycloak.models.ClientSessionContext; | 
|---|
|  |  |  | import org.keycloak.models.KeycloakSession; | 
|---|
|  |  |  | import org.keycloak.models.ProtocolMapperModel; | 
|---|
|  |  |  | import org.keycloak.models.UserSessionModel; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import java.util.Map; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public interface CASAttributeMapper { | 
|---|
|  |  |  | void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession); | 
|---|
|  |  |  | void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession, | 
|---|
|  |  |  | KeycloakSession session, ClientSessionContext clientSessionCtx); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | package org.keycloak.protocol.cas.mappers; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.keycloak.models.ProtocolMapperModel; | 
|---|
|  |  |  | import org.keycloak.models.UserModel; | 
|---|
|  |  |  | import org.keycloak.models.UserSessionModel; | 
|---|
|  |  |  | import org.keycloak.models.*; | 
|---|
|  |  |  | import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; | 
|---|
|  |  |  | import org.keycloak.provider.ProviderConfigProperty; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession) { | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession, | 
|---|
|  |  |  | KeycloakSession session, ClientSessionContext clientSessionCt) { | 
|---|
|  |  |  | UserModel user = userSession.getUser(); | 
|---|
|  |  |  | String first = user.getFirstName() == null ? "" : user.getFirstName() + " "; | 
|---|
|  |  |  | String last = user.getLastName() == null ? "" : user.getLastName(); | 
|---|
|  |  |  | 
|---|
|  |  |  | package org.keycloak.protocol.cas.mappers; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.keycloak.models.GroupModel; | 
|---|
|  |  |  | import org.keycloak.models.ProtocolMapperModel; | 
|---|
|  |  |  | import org.keycloak.models.UserSessionModel; | 
|---|
|  |  |  | import org.keycloak.models.*; | 
|---|
|  |  |  | import org.keycloak.models.utils.ModelToRepresentation; | 
|---|
|  |  |  | import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; | 
|---|
|  |  |  | import org.keycloak.provider.ProviderConfigProperty; | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession) { | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession, | 
|---|
|  |  |  | KeycloakSession session, ClientSessionContext clientSessionCt) { | 
|---|
|  |  |  | List<String> membership = new LinkedList<>(); | 
|---|
|  |  |  | boolean fullPath = useFullPath(mappingModel); | 
|---|
|  |  |  | for (GroupModel group : userSession.getUser().getGroups()) { | 
|---|
|  |  |  | 
|---|
|  |  |  | package org.keycloak.protocol.cas.mappers; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.keycloak.models.ClientSessionContext; | 
|---|
|  |  |  | import org.keycloak.models.KeycloakSession; | 
|---|
|  |  |  | import org.keycloak.models.ProtocolMapperModel; | 
|---|
|  |  |  | import org.keycloak.models.UserSessionModel; | 
|---|
|  |  |  | import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession) { | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession, | 
|---|
|  |  |  | KeycloakSession session, ClientSessionContext clientSessionCt) { | 
|---|
|  |  |  | setMappedAttribute(attributes, mappingModel, mappingModel.getConfig().get(CLAIM_VALUE)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | package org.keycloak.protocol.cas.mappers; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.keycloak.models.ProtocolMapperModel; | 
|---|
|  |  |  | import org.keycloak.models.UserModel; | 
|---|
|  |  |  | import org.keycloak.models.UserSessionModel; | 
|---|
|  |  |  | import org.keycloak.models.*; | 
|---|
|  |  |  | import org.keycloak.models.utils.KeycloakModelUtils; | 
|---|
|  |  |  | import org.keycloak.protocol.ProtocolMapperUtils; | 
|---|
|  |  |  | import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession) { | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession, | 
|---|
|  |  |  | KeycloakSession session, ClientSessionContext clientSessionCt) { | 
|---|
|  |  |  | UserModel user = userSession.getUser(); | 
|---|
|  |  |  | String attributeName = mappingModel.getConfig().get(ProtocolMapperUtils.USER_ATTRIBUTE); | 
|---|
|  |  |  | boolean aggregateAttrs = Boolean.valueOf(mappingModel.getConfig().get(ProtocolMapperUtils.AGGREGATE_ATTRS)); | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.keycloak.models.*; | 
|---|
|  |  |  | import org.keycloak.protocol.ProtocolMapperUtils; | 
|---|
|  |  |  | import org.keycloak.protocol.oidc.TokenManager; | 
|---|
|  |  |  | import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; | 
|---|
|  |  |  | import org.keycloak.provider.ProviderConfigProperty; | 
|---|
|  |  |  | import org.keycloak.representations.AccessToken; | 
|---|
|  |  |  | import org.keycloak.utils.RoleResolveUtil; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import java.util.*; | 
|---|
|  |  |  | import java.util.function.Predicate; | 
|---|
|  |  |  | import java.util.stream.Collectors; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public class UserClientRoleMappingMapper extends AbstractUserRoleMappingMapper { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession) { | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession, | 
|---|
|  |  |  | KeycloakSession session, ClientSessionContext clientSessionCtx) { | 
|---|
|  |  |  | String clientId = mappingModel.getConfig().get(ProtocolMapperUtils.USER_MODEL_CLIENT_ROLE_MAPPING_CLIENT_ID); | 
|---|
|  |  |  | String rolePrefix = mappingModel.getConfig().get(ProtocolMapperUtils.USER_MODEL_CLIENT_ROLE_MAPPING_ROLE_PREFIX); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | setAttribute(attributes, mappingModel, userSession, getClientRoleFilter(clientId, userSession), rolePrefix); | 
|---|
|  |  |  | if (clientId != null && !clientId.isEmpty()) { | 
|---|
|  |  |  | AccessToken.Access access = RoleResolveUtil.getResolvedClientRoles(session, clientSessionCtx, clientId, false); | 
|---|
|  |  |  | if (access == null) { | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static Predicate<RoleModel> getClientRoleFilter(String clientId, UserSessionModel userSession) { | 
|---|
|  |  |  | if (clientId == null) { | 
|---|
|  |  |  | return RoleModel::isClientRole; | 
|---|
|  |  |  | setAttribute(attributes, mappingModel, access.getRoles(), rolePrefix); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | // If clientId is not specified, we consider all clients | 
|---|
|  |  |  | Map<String, AccessToken.Access> allAccess = RoleResolveUtil.getAllResolvedClientRoles(session, clientSessionCtx); | 
|---|
|  |  |  | Set<String> allRoles = allAccess.values().stream().filter(Objects::nonNull) | 
|---|
|  |  |  | .flatMap(access -> access.getRoles().stream()) | 
|---|
|  |  |  | .collect(Collectors.toSet()); | 
|---|
|  |  |  | setAttribute(attributes, mappingModel, allRoles, rolePrefix); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | RealmModel clientRealm = userSession.getRealm(); | 
|---|
|  |  |  | ClientModel client = clientRealm.getClientByClientId(clientId.trim()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (client == null) { | 
|---|
|  |  |  | return RoleModel::isClientRole; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | boolean fullScopeAllowed = client.isFullScopeAllowed(); | 
|---|
|  |  |  | Set<RoleModel> clientRoleMappings = client.getRoles(); | 
|---|
|  |  |  | if (fullScopeAllowed) { | 
|---|
|  |  |  | return clientRoleMappings::contains; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Set<RoleModel> scopeMappings = new HashSet<>(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // CAS protocol does not support scopes, so pass null scopeParam | 
|---|
|  |  |  | Set<ClientScopeModel> clientScopes = TokenManager.getRequestedClientScopes(null, client); | 
|---|
|  |  |  | for (ClientScopeModel clientScope : clientScopes) { | 
|---|
|  |  |  | scopeMappings.addAll(clientScope.getScopeMappings()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return role -> clientRoleMappings.contains(role) && scopeMappings.contains(role); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static ProtocolMapperModel create(String clientId, String clientRolePrefix, | 
|---|
|  |  |  | 
|---|
|  |  |  | package org.keycloak.protocol.cas.mappers; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.keycloak.models.ProtocolMapperModel; | 
|---|
|  |  |  | import org.keycloak.models.UserModel; | 
|---|
|  |  |  | import org.keycloak.models.UserSessionModel; | 
|---|
|  |  |  | import org.keycloak.models.*; | 
|---|
|  |  |  | import org.keycloak.protocol.ProtocolMapperUtils; | 
|---|
|  |  |  | import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; | 
|---|
|  |  |  | import org.keycloak.provider.ProviderConfigProperty; | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession) { | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession, | 
|---|
|  |  |  | KeycloakSession session, ClientSessionContext clientSessionCt) { | 
|---|
|  |  |  | UserModel user = userSession.getUser(); | 
|---|
|  |  |  | String propertyName = mappingModel.getConfig().get(ProtocolMapperUtils.USER_ATTRIBUTE); | 
|---|
|  |  |  | String propertyValue = ProtocolMapperUtils.getUserModelValue(user, propertyName); | 
|---|
|  |  |  | 
|---|
|  |  |  | package org.keycloak.protocol.cas.mappers; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.keycloak.models.ClientSessionContext; | 
|---|
|  |  |  | import org.keycloak.models.KeycloakSession; | 
|---|
|  |  |  | import org.keycloak.models.ProtocolMapperModel; | 
|---|
|  |  |  | import org.keycloak.models.UserSessionModel; | 
|---|
|  |  |  | import org.keycloak.protocol.ProtocolMapperUtils; | 
|---|
|  |  |  | import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; | 
|---|
|  |  |  | import org.keycloak.provider.ProviderConfigProperty; | 
|---|
|  |  |  | import org.keycloak.representations.AccessToken; | 
|---|
|  |  |  | import org.keycloak.utils.RoleResolveUtil; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import java.util.ArrayList; | 
|---|
|  |  |  | import java.util.List; | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession) { | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession, | 
|---|
|  |  |  | KeycloakSession session, ClientSessionContext clientSessionCtx) { | 
|---|
|  |  |  | String rolePrefix = mappingModel.getConfig().get(ProtocolMapperUtils.USER_MODEL_REALM_ROLE_MAPPING_ROLE_PREFIX); | 
|---|
|  |  |  | setAttribute(attributes, mappingModel, userSession, role -> ! role.isClientRole(), rolePrefix); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | AccessToken.Access access = RoleResolveUtil.getResolvedRealmRoles(session, clientSessionCtx, false); | 
|---|
|  |  |  | if (access == null) { | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | setAttribute(attributes, mappingModel, access.getRoles(), rolePrefix); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static ProtocolMapperModel create(String realmRolePrefix, String name, String tokenClaimName) { | 
|---|
|  |  |  | 
|---|
|  |  |  | package org.keycloak.protocol.cas.mappers; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.keycloak.models.ClientSessionContext; | 
|---|
|  |  |  | import org.keycloak.models.KeycloakSession; | 
|---|
|  |  |  | import org.keycloak.models.ProtocolMapperModel; | 
|---|
|  |  |  | import org.keycloak.models.UserSessionModel; | 
|---|
|  |  |  | import org.keycloak.protocol.ProtocolMapperUtils; | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession) { | 
|---|
|  |  |  | public void setAttribute(Map<String, Object> attributes, ProtocolMapperModel mappingModel, UserSessionModel userSession, | 
|---|
|  |  |  | KeycloakSession session, ClientSessionContext clientSessionCt) { | 
|---|
|  |  |  | String noteName = mappingModel.getConfig().get(ProtocolMapperUtils.USER_SESSION_NOTE); | 
|---|
|  |  |  | String noteValue = userSession.getNote(noteName); | 
|---|
|  |  |  | if (noteValue == null) return; | 
|---|