Я наконец-то понял, как это сделать. В этом примере используется аутентификация JWT по умолчанию и пользовательская аутентификация в некоторых редких случаях. Обратите внимание, что из того, что я прочитал, Microsoft, похоже, не рекомендует писать свою собственную аутентификацию. Пожалуйста, используйте на свой страх и риск.
Сначала добавьте этот код в метод startup.cs ConfigureServices, чтобы обеспечить глобальное применение аутентификации.
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
Затем добавьте это, чтобы настроить схемы, которые вы хотите использовать (в нашем случае JWT и Custom).
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
// Jwt Authentication
.AddJwtBearer(options =>
{
options.Audience = ".......";
options.Authority = "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_...";
})
// Custom auth
.AddScheme<CustomAuthOptions,
CustomAuthHandler>(CustomAuthOptions.DefaultScheme, options => { });
Затем создайте класс для хранения пользовательских настроек аутентификации:
public class CustomAuthOptions : AuthenticationSchemeOptions
{
public const string Scheme = "custom auth";
public const string CustomAuthType = "custom auth type";
}
Наконец, добавьте обработчик аутентификации для реализации пользовательской логики аутентификации.
public class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{
public CustomAuthHandler(
IOptionsMonitor<CustomAuthOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock) : base(options, logger, encoder, clock)
{
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
// Auth logic goes here
if (!Request.Headers....)
{
return Task.FromResult(AuthenticateResult.Fail("Authentication Failed."));
}
// Create authenticated user
ClaimsPrincipal principal = .... ;
List<ClaimsIdentity> identities =
new List<ClaimsIdentity> {
new ClaimsIdentity(CustomAuthOptions.CustomAuthType)};
AuthenticationTicket ticket =
new AuthenticationTicket(
new ClaimsPrincipal(identities), CustomAuthOptions.Scheme);
return Task.FromResult(AuthenticateResult.Success(ticket));
}
}
Наконец, чтобы связать все это, добавьте атрибут авторизации к действиям, для которых вы хотите использовать пользовательскую авторизацию.
[HttpGet]
[Authorize(AuthenticationSchemes = CustomAuthOptions.Scheme)]
public HttpResponseMessage Get()
{
....
}
Теперь аутентификация JWT будет автоматически применяться ко всем действиям, а пользовательская аутентификация будет добавляться только к действиям с атрибутом Authorize, установленным для пользовательской схемы.
Надеюсь, это кому-нибудь поможет.