ASP.Net core 2: схема аутентификации по умолчанию игнорируется

Я пытаюсь создать собственный AuthenticationHandler в ASP.Net Core 2. Следуя таким темам, как ПО промежуточного слоя для проверки подлинности ASP.NET Core 2.0 и Почему схема аутентификации Asp.Net Core обязательна, я создал определенные классы. Регистрация происходит так:

services.AddAuthentication(
    options =>
    {
        options.DefaultScheme = Constants.NoOpSchema;
        options.DefaultAuthenticateScheme = Constants.NoOpSchema;
        options.DefaultChallengeScheme = Constants.NoOpSchema;
        options.DefaultSignInScheme = Constants.NoOpSchema;
        options.DefaultSignOutScheme = Constants.NoOpSchema; 
        options.DefaultForbidScheme = Constants.NoOpSchema;
    }
).AddScheme<CustomAuthOptions, CustomAuthHandler>(Constants.NoOpSchema, "Custom Auth", o => { });

Все работает, если конкретные контроллеры явно задают схему:

[Authorize(AuthenticationSchemes= Constants.NoOpSchema)]
[Route("api/[controller]")]
public class IndividualsController : Controller

Но мне бы не хотелось устанавливать схему, так как она должна добавляться динамически. Как только я удалю свойство схемы, вот так:

[Authorize]
[Route("api/[controller]")]
public class IndividualsController : Controller

Больше не работает.

Я бы надеялся, что настройка DefaultScheme Properties сделает эту работу. Что интересно, я не нашел особого обсуждения этой темы. Я здесь что-то делаю не так или мой ожидаемый результат неверен?

Обновлено: Спасибо за вопросы, это мне очень помогло. Похоже, отображение DefaultScheme используется промежуточным программным обеспечением аутентификации, которое я использовал только тогда, когда CustomAuthHandler не был на месте. Поэтому мне всегда приходилось добавлять AuthenticationMiddleware.

Edit2: К сожалению, это все еще не работает. Чтобы немного улучшить мой вопрос: я добавляю промежуточное ПО как обычно:

app.UseAuthentication();
app.UseMvc();

Теперь я попадаю в свой обработчик, который выглядит так:

public class NoOpAuthHandler : AuthenticationHandler<NoOpAuthOptions>
{
    public const string NoOpSchema = "NoOp";

    public NoOpAuthHandler(IOptionsMonitor<NoOpAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
    {
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync() => Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(Context.User, NoOpSchema)));
}

Но даже если я всегда возвращаю успех, я получаю 401. Я думаю, что мне нужно копнуть глубже и как бы установить некоторые утверждения, но, к сожалению, обработчики от Microsoft довольно сложно анализировать, поскольку они содержат много кода.

Вы добавили app.UseAuthentication() в свой конвейер промежуточного программного обеспечения?

Kahbazi 19.04.2018 10:39

какая ошибка возникает при удалении AuthenticationSchemes?

Neville Nazerane 19.04.2018 11:56

Что делает CustomAuthHandler?

Tratcher 19.04.2018 12:46

Я полагаю, вы знаете, но вы можете унаследовать атрибут авторизации, чтобы избежать AuthenticationSchemes = Constants.NoOpSchema

animalito maquina 19.04.2018 16:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
19
4
11 885
5

Ответы 5

Убедитесь, что у вас есть промежуточное ПО для аутентификации в конвейере и поместите его перед MVC.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ///

    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller}/{action=Index}/{id?}");
    });
    ///
}

ОБНОВИТЬ

попробуйте использовать этот код в методе HandleAuthenticateAsync.

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    List<Claim> claims = new List<Claim>();
    ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, Scheme.Name);
    ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
    AuthenticationTicket authenticationTicket = new AuthenticationTicket(claimsPrincipal, Scheme.Name);
    return AuthenticateResult.Success(authenticationTicket);
}

Еще одно замечание: в .NET Core 3/5 убедитесь, что у вас есть app.UseAuthentication ДО app.UseAuthorization(). Идут 2 часа моего дня :)

René Sackers 09.04.2021 14:21

Ответ ASP.Net Core 2

Вы должны установить политику авторизации по умолчанию, привязанную к вашей схеме аутентификации:

services.AddAuthorization(options => {
  options.DefaultPolicy = new AuthorizationPolicyBuilder()
    .AddAuthenticationSchemes(Constants.NoOpSchema)
    .RequireAuthenticatedUser()
    .Build();
});

Ответ ASP.Net Core 3

В ASP.Net Core 3 все, по-видимому, немного изменилось, поэтому вам нужно создать метод расширения для добавления обработчика аутентификации:

public static class NoOpAuthExtensions
{
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder)
        => builder.AddNoOpAuth(NoOpAuthHandler.NoOpSchema, _ => { });
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, Action<NoOpAuthOptions> configureOptions)
        => builder.AddNoOpAuth(NoOpAuthHandler.NoOpSchema, configureOptions);
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, string authenticationScheme, Action<NoOpAuthOptions> configureOptions)
        => builder.AddNoOpAuth(authenticationScheme, null, configureOptions);
    public static AuthenticationBuilder AddNoOpAuth(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<NoOpAuthOptions> configureOptions)
    {
        return builder.AddScheme<NoOpAuthOptions, NoOpAuthHandler>(authenticationScheme, displayName, configureOptions);
    }
}

И используйте его в своем методе ConfigureServices следующим образом:

services
  .AddAuthentication(NoOpAuthHandler.NoOpSchema)
  .AddNoOpAuth();

Это сработало для меня. Я не уверен, для чего на самом деле предназначен DefaultAuthenticateScheme, но он не для установки схемы [Авторизация] по умолчанию.

King John 07.02.2020 16:37

попробуй это.

services.AddAuthentication(
        options =>
        {
            options.DefaultAuthenticateScheme = "Cookie"
            options.DefaultChallengeScheme = Constants.NoOpSchema;
            options.DefaultSignInScheme = "Cookie";
        }
    )
    .AddCookie("Cookie")
    .AddScheme<CustomAuthOptions, CustomAuthHandler>(Constants.NoOpSchema, "Custom Auth", o => { });

Я страдаю от этого часами, в моем случае проблема заключалась в классе AuthenticationMiddleware по умолчанию. Точнее; Если вы установите ClaimsPrincipal в настраиваемом промежуточном программном обеспечении в конвейере запросов, как показано ниже:

HttpContext.context.User = new ClaimsPrincipal(identity); это переопределит ваши настройки конфигурации аутентификации по умолчанию,

Что я сделал, чтобы решить; удалите пользовательское промежуточное ПО и добавьте app.UseAuthentication(); в раздел Configure в Startup.cs, а атрибут Authroize проверяет все, что установлено в разделе config по умолчанию;

Вот мой;

services.AddAuthentication(x =>
            {
                x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateLifetime = true,
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ClockSkew = TimeSpan.Zero
                };
            });

в .NET Core 3.1 мне пришлось вручную добавить [Authorize(AuthenticationSchemes = "Bearer")] вместо простого [Authorize] в конечные точки, чтобы аутентификация работала так, как я ожидал. Следующее изменение конфигурации решило проблему:

services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = "Bearer";
    })

Другие вопросы по теме