In meiner Asp.Net Core-Anwendung möchte ich benutzerdefinierte Ansprüche zu meiner ClaimsIdentity hinzufügen, damit ich auf diese in verschiedenen Schichten meiner Anwendung zugreifen kann. Um dies zu erreichen Ich habe folgenden CodeASP.NET Core 2.0.3 ClaimsTransformer in Kombination mit HttpContextAccessor, Ansprüche werden gelöscht
Startup
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddTransient<IPrincipal>(
provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);
services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
ClaimsTransformer
public class ClaimsTransformer : IClaimsTransformation
{
private readonly IUnitOfWork _unitOfWork;
private readonly IPrincipal _principal;
public ClaimsTransformer(IUnitOfWork unitOfWork, IPrincipal principal)
{
_unitOfWork = unitOfWork;
_principal = principal;
}
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var currentPrincipal = (ClaimsIdentity)_principal.Identity;
var identity = (ClaimsIdentity)principal.Identity;
if (currentPrincipal.Claims.All(p => p.Type != "UserId"))
{
var person = _unitOfWork.PersonRepository.GetPersonBySubjectId(principal.Claims.First(p => p.Type == "sub").Value);
person.Wait();
if (person.Result != null)
{
currentPrincipal.AddClaim(new Claim("UserId", person.Result.Id.ToString()));
currentPrincipal.AddClaim(new Claim("TenantId", person.Result.PersonTeams.FirstOrDefault(p => p.Team.TeamType == TeamType.OrganizationTeam)?.Team.OrganizationId.ToString()));
if (principal.Claims.Any(p => p.Type == "Admin"))
{
currentPrincipal.AddClaim(new Claim("Admin", "True"));
}
}
foreach (var claim in identity.Claims)
{
currentPrincipal.AddClaim(claim);
}
}
return Task.FromResult(principal);
}
}
Was ich nicht verstehe, ist, wenn ich laufe meine Claimstransformation und ich Schritt durch den Code , alle erforderlichen Ansprüche sind verfügbar, aber wenn ich mein IPrincipal in eine benutzerdefinierte Klasse injiziere, ist die Anspruchsauflistung leer, wenn ich die ClaimsTransformation nicht verwende, die cl Ziele sind über das injizierte IPrincipal verfügbar.
Um dieses Problem zu beheben, füge ich das IPrincipal dem ClaimsTransformer hinzu, dupliziere die Ansprüche aus dem TransformAsync-Eingabeparameter und füge die UserId und TenantId hinzu. Diese funktioniert, aber das Problem, das ich habe ist, dass ich nicht verstehe, warum die Ansprüche gestrichen werden, wenn ich die ClaimsTransformer laufen und warum muss ich hinzufügen, diese hacken