Средство проверки подлинности ASP.NET Core 2.0

С Core 1.1 последовал за советом @blowdart и реализовал пользовательское промежуточное ПО:

qaru.site/info/42950/...

Он работал следующим образом:

  • Произошло промежуточное ПО. Выбрал токен из заголовков запросов.
  • Проверено токен, и если он действителен, построил идентификатор (ClaimsIdentity), содержащий несколько претензий, которые затем добавлены через HttpContext.User.AddIdentity();
  • В ConfigureServices с помощью services.AddAuthorization Я добавил политику, требующую требования, предоставляемые промежуточным программным обеспечением.
  • В контроллерах/действиях я использовал бы [Authorize (Роли = "роль, которую добавила промежуточное ПО)]

Это несколько работает с 2.0, за исключением того, что если токен недействителен (шаг 2 выше), и требование никогда не добавляется, я получаю "No authenticationScheme был указан, и не было обнаружено DefaultChallengeScheme".

Итак, теперь я читаю, что auth изменился в версии 2.0:

https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x

Какой правильный путь для меня сделать то же самое в ASP.NET Core 2.0? Я не вижу примера для подлинной аутентификации...

Спасибо

Ответ 1

Итак, после долгого дня, пытаясь решить эту проблему, я, наконец, понял, как Microsoft хочет, чтобы мы сделали собственные обработчики проверки подлинности для своей новой установки однопользовательского ПО в основном 2.0.

После просмотра некоторой документации по MSDN я нашел класс под названием AuthenticationHandler<TOption>, который реализует интерфейс IAuthenticationHandler.

Оттуда я нашел целую базу кода с существующими схемами аутентификации, расположенными в https://github.com/aspnet/Security

Внутри одного из них он показывает, как Microsoft реализует схему аутентификации JwtBearer. (https://github.com/aspnet/Security/tree/dev/src/Microsoft.AspNetCore.Authentication.JwtBearer)

Я скопировал большую часть этого кода в новую папку и очистил все, что связано с JwtBearer.

В классе JwtBearerHandler (который расширяет AuthenticationHandler<>) существует переопределение для Task<AuthenticateResult> HandleAuthenticateAsync()

Я добавил в наше старое промежуточное ПО для настройки претензий через пользовательский сервер токенов и все еще сталкивался с некоторыми проблемами с разрешениями, просто выплевывая 200 OK вместо 401 Unauthorized, когда токен был недействительным, и никаких претензий не было настроен.

Я понял, что переопределил Task HandleChallengeAsync(AuthenticationProperties properties), который по какой-либо причине используется для установки разрешений через [Authorize(Roles="")] в контроллере.

После удаления этого переопределения код работал и успешно выбрал 401, когда разрешения не совпали.

Основной вывод из этого заключается в том, что теперь вы не можете использовать собственное промежуточное программное обеспечение, вы должны реализовать его с помощью AuthenticationHandler<>, и при использовании services.AddAuthentication(...) вы должны установить DefaultAuthenticateScheme и DefaultChallengeScheme.

Вот пример того, как все это должно выглядеть:

В Startup.cs/ConfigureServices() добавить:

services.AddAuthentication(options =>
{
    // the scheme name has to match the value we're going to use in AuthenticationBuilder.AddScheme(...)
    options.DefaultAuthenticateScheme = "Custom Scheme";
    options.DefaultChallengeScheme = "Custom Scheme";
})
.AddCustomAuth(o => { });

В Startup.cs/Configure() добавить:

app.UseAuthentication();

Создайте новый файл CustomAuthExtensions.cs

public static class CustomAuthExtensions
{
    public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder, Action<CustomAuthOptions> configureOptions)
    {
        return builder.AddScheme<CustomAuthOptions, CustomAuthHandler>("Custom Scheme", "Custom Auth", configureOptions);
    }
}

Создайте новый файл CustomAuthOptions.cs

public class CustomAuthOptions: AuthenticationSchemeOptions
{
    public CustomAuthOptions()
    {

    }
}

Создайте новый файл CustomAuthHandler.cs

internal class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{
    public CustomAuthHandler(IOptionsMonitor<CustomAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
    {
        // store custom services here...
    }
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        // build the claims and put them in "Context"; you need to import the Microsoft.AspNetCore.Authentication package
        return AuthenticateResult.NoResult();
    }
}

Ответ 2

В Identity от Core 1.x до Core 2.0 произошли значительные изменения, так как в статье вы ссылаетесь. Основным изменением является уход от подхода промежуточного программного обеспечения и использование инъекции зависимостей для настройки пользовательских сервисов. Это обеспечивает гораздо большую гибкость при настройке Identity для более сложных реализаций. Поэтому вы хотите уйти от подхода промежуточного программного обеспечения, о котором вы упомянули выше, и перейти к услугам. Для достижения этой цели выполните действия по миграции в указанной статье. Начните с замены app.UseIdentity на app.UseAuthentication. UseIdentity обесценивается и не поддерживается в будущих версиях. Полный пример того, как вставить преобразование пользовательских претензий и выполнить авторизацию по требованию просмотреть это сообщение в блоге.