Я столкнулся с проблемой при реализации нескольких схем авторизации в ASP. Net Базовом приложении. Допустим, они объявлены так в Startup.cs
public void ConfigureServices(IServiceCollection services)
{
AuthenticationBuilder builder = services
.AddAuthentication()
.AddBasicAuthentication(o => { o.Realm = "MyRealm"; })
.AddApiKeyAuthentication()
.AddBearerToken(opt => { });
}
Каждая из этих схем обеспечивает собственную реализацию AuthenticationHandler , возвращающую ClaimsIdentity в случае успеха. Но в каждом случае структура претензий является незаметной, т.е. ApiKeyAuthentication может вернуть ClaimsIdentity с данными, чувствительными к бизнесу, которые хранятся в претензии "api_service", в то время как BearerTokenScheme сохранит их в подпункте претензии, а я не имею контроля через это. Поэтому, если я хотел бы использовать эту информацию в контроллере, чтобы связать некоторый процесс со службой, которая вызвала мой метод API, я должен реализовать несколько сложных логик c, которые бы анализировали текущий ClaimsIdentity , его аутентификацию Схема и набор требований. Вместо этого я хотел бы реализовать некую трансформацию ClaimsIdentity в MyServiceClaimsIdentity , которая бы выявила заявки удобным способом, чтобы я мог легко использовать их в своем коде контроллеров:
public class MyServiceClaimsIdentity: IIdentity
{
private readonly ClaimsIdentity innerIdentity;
public Guid? UserId {get; }
public string UserName {get; }
public string ServiceName {get; }
public MyServiceClaimsIdentity(ClaimsIdentity identity)
{
this.innerIdentity = identity;
TransformClaimsIntoProperties();
}
private void TransformClaimsIntoProperties()
{
......
}
}
I ' мы пытались реализовать некий «преобразующий» AuthenticationHandler , который мог бы выдать MyServiceClaimsIdentity после того, как все другие обработчики выдадут свой ClaimsIdentity.
public class FinalAuthenticationHandler : AuthenticationHandler<FinalAuthenticationOptions>
{
public FinalAuthenticationHandler(
IOptionsMonitor<FinalAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock)
: base(options, logger, encoder, clock)
{
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (!this.Context.User.Identity.IsAuthenticated)
{
return null;
}
var identity = new MyServiceClaimsIdentity(this.Context.User.Identity);
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, this.Scheme.Name);
return AuthenticateResult.Success(ticket);
}
}
Слишком плохо на этом этапе this.Context.User.Identity не содержит никакой информации о пользователе, поэтому я не понимаю, куда поместить этот лог трансформации c или как мне получить текущий ClaimsIdentity, предоставленный другим обработчиком, в моем FinalAuthenticationHandler . Любая помощь будет оценена.