using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.Security
{
///
/// A
///
public class BackOfficeClaimsPrincipalFactory : UserClaimsPrincipalFactory
{
///
/// Initializes a new instance of the class.
///
/// The user manager
/// The
public BackOfficeClaimsPrincipalFactory(UserManager userManager, IOptions optionsAccessor)
: base(userManager, optionsAccessor)
{
}
protected virtual string AuthenticationType { get; } = Constants.Security.BackOfficeAuthenticationType;
///
protected override async Task GenerateClaimsAsync(BackOfficeIdentityUser user)
{
// NOTE: Have a look at the base implementation https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Extensions.Core/src/UserClaimsPrincipalFactory.cs#L79
// since it's setting an authentication type which is not what we want.
// so we override this method to change it.
// get the base
ClaimsIdentity baseIdentity = await base.GenerateClaimsAsync(user);
// now create a new one with the correct authentication type
var id = new ClaimsIdentity(
AuthenticationType,
Options.ClaimsIdentity.UserNameClaimType,
Options.ClaimsIdentity.RoleClaimType);
// and merge all others from the base implementation
id.MergeAllClaims(baseIdentity);
// ensure our required claims are there
id.AddRequiredClaims(
user.Id,
user.UserName,
user.Name,
user.CalculatedContentStartNodeIds,
user.CalculatedMediaStartNodeIds,
user.Culture,
user.SecurityStamp,
user.AllowedSections,
user.Roles.Select(x => x.RoleId).ToArray());
// now we can flow any custom claims that the actual user has currently
// assigned which could be done in the OnExternalLogin callback
id.MergeClaimsFromBackOfficeIdentity(user);
return id;
}
}
}