2020-12-03 20:30:35 +11:00
using System ;
2020-04-02 08:08:09 +01:00
using System.Linq ;
using System.Security.Claims ;
using System.Threading.Tasks ;
using Microsoft.AspNetCore.Identity ;
using Microsoft.Extensions.Options ;
2021-02-17 14:17:38 +01:00
using Umbraco.Extensions ;
2020-04-02 08:08:09 +01:00
2021-02-15 12:01:12 +01:00
namespace Umbraco.Cms.Core.Security
2020-04-02 08:08:09 +01:00
{
2020-12-03 20:30:35 +11:00
/// <summary>
/// A <see cref="UserClaimsPrincipalFactory{TUser}" for the back office/>
/// </summary>
public class BackOfficeClaimsPrincipalFactory : UserClaimsPrincipalFactory < BackOfficeIdentityUser >
2020-04-02 08:08:09 +01:00
{
2020-12-03 20:30:35 +11:00
/// <summary>
/// Initializes a new instance of the <see cref="BackOfficeClaimsPrincipalFactory"/> class.
/// </summary>
/// <param name="userManager">The user manager</param>
/// <param name="optionsAccessor">The <see cref="BackOfficeIdentityOptions"/></param>
public BackOfficeClaimsPrincipalFactory ( UserManager < BackOfficeIdentityUser > userManager , IOptions < BackOfficeIdentityOptions > optionsAccessor )
2020-04-02 08:08:09 +01:00
: base ( userManager , optionsAccessor )
{
}
2021-03-29 17:37:58 +11:00
protected virtual string AuthenticationType { get ; } = Constants . Security . BackOfficeAuthenticationType ;
2020-12-03 20:30:35 +11:00
/// <inheritdoc />
2021-03-29 17:37:58 +11:00
protected override async Task < ClaimsIdentity > GenerateClaimsAsync ( BackOfficeIdentityUser user )
2020-04-02 08:08:09 +01:00
{
2021-03-29 17:37:58 +11:00
// 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.
2020-04-04 19:58:09 +01:00
2021-03-29 17:37:58 +11:00
// get the base
2020-12-03 20:30:35 +11:00
ClaimsIdentity baseIdentity = await base . GenerateClaimsAsync ( user ) ;
2020-04-04 19:58:09 +01:00
2021-03-29 17:37:58 +11:00
// 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
2021-03-29 18:05:13 +11:00
id . AddRequiredClaims (
2020-04-02 08:08:09 +01:00
user . Id ,
user . UserName ,
user . Name ,
user . CalculatedContentStartNodeIds ,
user . CalculatedMediaStartNodeIds ,
user . Culture ,
user . SecurityStamp ,
user . AllowedSections ,
user . Roles . Select ( x = > x . RoleId ) . ToArray ( ) ) ;
2021-03-05 15:36:27 +01:00
// now we can flow any custom claims that the actual user has currently
// assigned which could be done in the OnExternalLogin callback
2021-03-29 18:05:13 +11:00
id . MergeClaimsFromBackOfficeIdentity ( user ) ;
2021-03-05 15:36:27 +01:00
2021-03-29 17:37:58 +11:00
return id ;
2020-06-03 18:10:35 +10:00
}
2020-04-02 08:08:09 +01:00
}
}