JWT-авторизация всегда возвращает 401 Unauthorized

Эндпоинт постоянно возвращает 401 Unauthorized. Использовал этот туториал.

[HttpGet]
[Authorize]
public async Task<ActionResult<User>> Get(HttpContext httpContext)
{
    return Ok();
}

Program.cs:

using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using backend.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthorization();

IConfigurationSection jwtConfig = builder.Configuration.GetSection("Jwt");
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer((options) =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidIssuer = jwtConfig.GetValue<string>("Issuer"),
        ValidateAudience = true,
        ValidAudience = jwtConfig.GetValue<string>("Audience"),
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        RequireExpirationTime = true,
        IssuerSigningKey = new SymmetricSecurityKey(File.ReadAllBytes(jwtConfig.GetValue<string>("Key")))
    };
});

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddDbContext<ApplicationContext>((options) => options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddSingleton<EmailChecker>();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

Код генератора токена:

[HttpPost("login")]
public ActionResult Login(UserLogin req)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    User user;

    try
    {
        user = context.Users.First((x) => x.Email == req.Email && x.Verified);
    }
    catch (InvalidOperationException)
    {
        return BadRequest("userNotFound");
    }

    if (!VerifyPasswordHash(req.Password, user.PasswordHash, user.PasswordSalt))
    {
        return BadRequest("invalidPassword");
    }

    return Ok(CreateToken(user));
}

private string CreateToken(User user)
{
    ClaimsIdentity claims = new ClaimsIdentity(new Claim[]{
        new Claim(ClaimTypes.Name, user.Id.ToString()),
    });

    IConfigurationSection jwtConfig = cfg.GetSection("Jwt");

    SecurityTokenDescriptor desc = new SecurityTokenDescriptor
    {
        Subject = claims,
        IssuedAt = DateTime.UtcNow,
        Expires = DateTime.UtcNow.AddDays(2),
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(privateKey), SecurityAlgorithms.HmacSha256Signature),
        Issuer = jwtConfig.GetValue<string>("Issuer"),
        Audience = jwtConfig.GetValue<string>("Audience"),
    };

    JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler();
    SecurityToken tok = jwtHandler.CreateToken(desc);

    return jwtHandler.WriteToken(tok);
}

Запрос к генератору токена:1

Запрос к защищенному токеном эндпоинту: введите сюда описание изображения

введите сюда описание изображения


Ответы (1 шт):

Автор решения: Nikita Nikiforov

По каким-то причинам ASP.NET Core отказывает в авторизации, если соединение не защищено. Удаление app.UseHttpsRedirection() решает проблему.

→ Ссылка