/// <summary> /// Transforms the claims from AAD to well-known claims. /// </summary> /// <param name="principal">The current <see cref="System.Security.Claims.ClaimsPrincipal"/></param> private static void NormalizeClaims(ClaimsPrincipal principal) { Guard.ArgumentNotNull(principal, nameof(principal)); var identity = principal.Identities.First(); if (!identity.IsAuthenticated) { throw new InvalidOperationException("The supplied principal is not authenticated."); } var email = principal.FindFirst(ClaimTypes.Upn)?.Value; if (!string.IsNullOrWhiteSpace(email)) { identity.AddClaim(new Claim(ClaimTypes.Email, email)); } var name = principal.GetDisplayNameValue(); if (!string.IsNullOrWhiteSpace(name)) { // It looks like AAD does something strange here, but it's actually the JwtSecurityTokenHandler making assumptions // about the claims from AAD. It takes the unique_name claim from AAD and maps it to a ClaimTypes.Name claim, which // is the default type for a name claim for our identity. If we don't remove the old one, there will be two name claims, // so let's get rid of the first one. var previousNameClaim = principal.FindFirst(ClaimTypes.Name); if (previousNameClaim != null) { identity.RemoveClaim(previousNameClaim); } identity.AddClaim(new Claim(identity.NameClaimType, name)); } }