Атрибут авторизации всегда возвращает 401 после обновления до NET Core 3.1.

Мой NET Core 3.1 rest API в настоящее время возвращает ошибку 401 при вызовах, отмеченных атрибутом [Authorize]. Вызовы, которые не имеют атрибута авторизации, или те, которые разрешают анонимность, или если я удаляю атрибут авторизации из контроллера, будут успешными.

Недавно я обновил API с Core 2 до Core 3.1, что наводит меня на мысль, что код ожидается по-разному между 2 и 3.1.

Судя по другим вопросам на StackOverflow и в Интернете, большинство указывает на порядок элементов в функции «Настройка» при запуске, хотя мой выглядит так, как в документах Microsoft. Я не изменил свой код генерации токенов с момента обновления с 2 до 3.1. Токены выглядят действительными, когда я их получаю и проверяю в JWT.io, но, как и раньше, при запуске вызова через Postman или из внешнего приложения вызов немедленно 401s на этапе авторизации.

Ниже приведены несколько фрагментов кода:

Startup.cs — Конфигуресервисс

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
        services.AddControllers();

        // Get appsettings from config file
        var appSettingsSection = Configuration.GetSection("AppSettings");
        services.Configure<AppSettings>(appSettingsSection);
        var appSettings = appSettingsSection.Get<AppSettings>();

        services.AddDbContext<MuglensContext>(options => options.UseSqlServer(appSettings.DBConnection));

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.RequireHttpsMetadata = false;
            options.SaveToken = true;
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(appSettings.JWTKey))
            };
        });
        // Underneath this is adding of scoped services

Startup.cs — Настройка

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors(builder => builder
            .WithOrigins(Configuration["Origins"])
            .AllowAnyHeader()
            .AllowAnyMethod()
        );

        //AuthAppBuilderExtensions.UseAuthentication(app);
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });

    }

AuthService.cs — сгенерировать токен

    private string GenerateToken(string email, string userID)
    {
        var claims = new[]
        {
            new Claim("email", email),
            new Claim("userID", userID)
        };

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_settings.JWTKey));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            issuer: _settings.Origins,
            audience: _settings.Origins,
            claims: claims,
            expires: DateTime.Now.AddMinutes(45),
            signingCredentials: creds);

        return new JwtSecurityTokenHandler().WriteToken(token);
    }

Любая помощь приветствуется.


person Chris Dye    schedule 25.05.2020    source источник


Ответы (2)


Вы пытались проверить схему JWT в атрибуте Authoize?

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]` 

в пространстве имен Microsoft.AspNetCore.Authentication.JwtBearer.

И в ваших сервисах зарегистрируйте эту схему, например

services.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
   ...
person Henkolicious    schedule 25.05.2020
comment
К сожалению, это не сработало. Я полагаю, что это уже описано в методе Configure options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - person Chris Dye; 26.05.2020

Я взял довольно длительный перерыв в проекте, но понял это, вернувшись к нему на прошлой неделе. Проблема была связана с моей аудиторией и настройками эмитента в стартапе. У меня были значения ValidateIssuer ValidateAudience, установленные в true, но не было никаких значений в ValidIssuer и ValidAudience.

После заполнения этих значений код работает должным образом.

person Chris Dye    schedule 25.07.2020