Claims mapping script

This sample web script automatically maps claims from an external login provider to user profile properties, such as assigning roles during user authentication.

External login providers send information about logged-in users as claims, which vary depending on the provider. In this example, Google is used as the login provider. Google provides two claims: givenname and surname. The script assumes the M.UserProfile entity definition includes FirstName and LastName properties and maps the givenname and surname claims to those properties.

Before you begin
  • Configure the schema editor to include the required properties that aren't included by default, such as FirstName and LastName.

  • Ensure the external login provider is integrated with Content Hub and that it provides claims for mapping.

Script

RequestResponse
using System.Linq;
using System.Security.Claims;

if (Context.ExternalUserInfo?.Claims == null) return;

var firstName = Context.ExternalUserInfo.Claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName)?.Value;
var lastName = Context.ExternalUserInfo.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname)?.Value;

if (string.IsNullOrEmpty(firstName) && string.IsNullOrEmpty(lastName)) return; // No first or lastname claims found, nothing to do.

var userToUserProfile = await Context.User.GetRelationAsync<IParentToOneChildRelation>("UserToUserProfile");
if (!userToUserProfile.Child.HasValue) throw new InvalidOperationException("The logged on user has no user-profile.");

var profile = await MClient.Entities.GetAsync(userToUserProfile.Child.Value); 
if (profile == null) throw new InvalidOperationException("The logged on user has no user-profile.");

if (!string.IsNullOrEmpty(firstName))
{
  profile.SetPropertyValue("FirstName", firstName);
}

if (!string.IsNullOrEmpty(lastName))
{
  profile.SetPropertyValue("LastName", lastName);
}

await MClient.Entities.SaveAsync(profile);

Script explanation

This section steps through the script in execution order, explaining each part. The numbered items describe the sequence, not instructions to perform.

  1. Include the libraries to be used during run time.

    RequestResponse
    using System.Linq;
    using System.Security.Claims;
    
  2. Users can log in using either basic authentication (with a username and password) or using an external login provider. If the user has logged in using basic authentication, Context.ExternalUserInfo will be null, meaning there are no claims to map, so the script exits.

    RequestResponse
    if (Context.ExternalUserInfo?.Claims == null) return;
    
  3. If the user is logged in using an external provider, extract the required values from the provided claims. These claims are defined as constants on the ClaimTypes class.

    RequestResponse
    var firstName = Context.ExternalUserInfo.Claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName)?.Value;
    var lastName = Context.ExternalUserInfo.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname)?.Value;
    
  4. If no givenname or surname claims are provided, there is nothing to map, so the script exits.

    RequestResponse
    if (string.IsNullOrEmpty(firstName) && string.IsNullOrEmpty(lastName)) return;
    
  5. Load the logged-in user's profile, as specified in Context.User. This profile is linked to the user through the UserToUserProfile relation, and every user is expected to have an associated profile. If the user's profile is not found, the script exits.

    RequestResponse
    var userToUserProfile = await Context.User.GetRelationAsync<IParentToOneChildRelation>("UserToUserProfile");
    if (!userToUserProfile.Child.HasValue) throw new InvalidOperationException("The logged on user has no user-profile.");
    
    var profile = await MClient.Entities.GetAsync(userToUserProfile.Child.Value); 
    if (profile == null) throw new InvalidOperationException("The logged on user has no user-profile.");
    
  6. Populate the FirstName and LastName properties of the profile entity. If one of the claims has not been provided, it is skipped.

    RequestResponse
    if (!string.IsNullOrEmpty(firstName))
    {
      profile.SetPropertyValue("FirstName", firstName);
    }
    
    if (!string.IsNullOrEmpty(lastName))
    {
      profile.SetPropertyValue("LastName", lastName);
    }
    
  7. Store the supplied user profile changes in the database.

    RequestResponse
    await MClient.Entities.SaveAsync(profile);
    

Setup

  • Create, publish, and enable a User sign-in script.

Do you have some feedback for us?

If you have suggestions for improving this article,