Search code examples
asp.netasp.net-identityopenid-connectaspnet-contrib

How to specify the destination for an existing ClaimsIdentity?


I'm using below code to create a ClaimIdentity in OpenIdConnectServerProvider.AuthorizationProvider. But the identity.Name is not searlized. How to allow the OpenIdConnectServer serarlize the name? Thanks.

The previous question is here How to create a ClaimIdentity in asp.net 5

var user = await userManager.FindByNameAsync(context.UserName);
var factory = context.HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<ApplicationUser>>();
var identity = await factory.CreateAsync(user);                
context.Validated(new ClaimsPrincipal(identity));       

Solution

  • To avoid leaking confidential data, AspNet.Security.OpenIdConnect.Server refuses to serialize the claims that don't explicitly specify a destination.

    To serialize the name (or any other claim), you can use the .SetDestinations extension:

    var principal = await factory.CreateAsync(user);
    
    var name = principal.FindFirst(ClaimTypes.Name);
    if (name != null) {
        // Use "id_token" to serialize the claim in the identity token or "access_token"
        // to serialize it in the access token. You can also specify both destinations.
        name.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken,
                             OpenIdConnectConstants.Destinations.IdentityToken);
    }
    
    context.Validate(principal);
    

    When adding a claim, you can also use the AddClaim extension taking a destinations parameter:

    identity.AddClaim(ClaimTypes.Name, "Pinpoint",
         OpenIdConnectConstants.Destinations.AccessToken,
         OpenIdConnectConstants.Destinations.IdentityToken);