在没有 AAD 的情况下,在 Azure 发送令牌的 Web 应用中调用 API 时出现 401 错误

401 error at calling APIs in Web App in Azure sending token, without AAD

提问人:Marcelo Montagne 提问时间:11/15/2023 更新时间:11/15/2023 访问量:38

问:

我有一个在 .Net 6 和 React(相同的解决方案)中构建的应用程序,我使用 Microsoft.AspNetCore.Authentication.JwtBearer Version=“6.0.16” 和 Microsoft.AspNetCore.Identity.EntityFrameworkCore Version=“6.0.16” 来管理用户身份验证。该应用程序托管在 Azure Web App 上,直到几天前它开始引发 401 错误时,它才运行良好。身份验证 API 返回一个有效的令牌,然后将其发送并包含在请求标头中的其他 API,但这些 API 会不断返回 401。使用 Postman 也会抛出 401。在本地,它不会发生。

我没有使用 AAD,所以我明白没有必要配置范围?我不确定。我的 Azure Web 应用没有任何授权配置,但直到几天前才运行良好。感谢您的帮助!

这是我从服务器端和代码进行的配置

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "Host": {
    "CORS": "xxxxxxxxxxxxxxxxxxxxxxxxx"
  },
  "ConnectionStrings": {
    "DBConnection": "XXXXXXXXXXXXXXXXXXXXXXX",
  },
  "JWTSettings": {
    "Key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "Issuer": "CoreIdentity",
    "Audience": "CoreIdentityUser",
    "DurationInMinutes": 30
  },
  "PageSizeGrids": 20,
  "CultureSettings": {
    "CultureName": "en-US",
    "NumberDecimalSeparator": ".",
    "NumberGroupSeparator": ","
  },
  "EPPlus": {
    "ExcelPackage": {
      "LicenseContext": "NonCommercial"
    }
  },
  "EmailSettings": {
    "EmailHost": "XXXXXXXXXXXXXXXXX",
    "EmailPassword": "XXXXXXXXXXXXXXXXX" 
  },
  "StorageAccount": {
    "Key": "XXXXXXXXXXXXXXXXXXXXXX",
    "StorageAccountName": "XXXXXXXXXXXXXXXX"
  },


}

程序.cs



var builder = WebApplication.CreateBuilder(args);

builder.Services.AddApplicationInfrastructure();
builder.Services.AddControllers(options =>
    options.Filters.Add<ApiExceptionFilterAttribute>()).AddJsonOptions(opt =>
    {
        opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    });

builder.Services.AddPersistenceInfrastructure(builder.Configuration);
builder.Services.AddSharedInfrastructure(builder.Configuration);
builder.Services.AddScoped<IAuthenticatedUserService, AuthenticatedUserService>();


builder.Services.Configure<DataProtectionTokenProviderOptions>(opt => //horas que dura el link de reseteo de password
   opt.TokenLifespan = TimeSpan.FromHours(2));

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(option =>
{
    option.AddPolicy("myCorsPolicy",
        builder =>
        {
            {
                //builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin();
                builder.AllowAnyHeader().AllowAnyMethod().AllowCredentials()

                .SetIsOriginAllowed(origin =>
                {
                    if (origin.StartsWith("https://example.com")) return true;
                    return false;
                });
            }
        });
});



var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{

    app.UseHsts();
}

app.UseHttpsRedirection();

var supportedCultures = new[]
{
     new CultureInfo("es-AR"),
 new CultureInfo("en-US"),
 new CultureInfo("es"),
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture("es-AR"),
    // Formatting numbers, dates, etc.
    SupportedCultures = supportedCultures,
    // UI strings that we have localized.
    SupportedUICultures = supportedCultures
});


app.UseStaticFiles();
app.UseCors("myCorsPolicy");
app.UseRouting();


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


app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action=Index}/{id?}").RequireCors("myCorsPolicy");


app.MapFallbackToFile("index.html"); ;

using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;
    var loggerFactory = services.GetRequiredService<ILoggerFactory>();
    try
    {
        var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
        var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();

        await DefaultRoles.SeedAsync(userManager, roleManager);
        await DefaultSuperAdmin.SeedAsync(userManager, roleManager);
    }
    catch (Exception ex)
    {
        //Log.Warning(ex, "An error occurred seeding the DB");
    }
    finally
    {
        //Log.CloseAndFlush();
    }
}

app.Run();
public static void AddPersistenceInfrastructure(this IServiceCollection services, IConfiguration configuration)
        {
            string? dbConnectionString;
            string? jWTSettingsKey;
            if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
            {
                dbConnectionString = configuration.GetConnectionString("DBConnection");
                jWTSettingsKey = configuration["JWTSettings:Key"];
            }
            else
            {
                dbConnectionString = Environment.GetEnvironmentVariable("SQLAZURECONNSTR_DbConnectionAzure");
                jWTSettingsKey = Environment.GetEnvironmentVariable("APPSETTING_JWT_KEY");
            }


            services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(dbConnectionString,
                    b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName))
            ,ServiceLifetime.Transient);
            services.AddIdentity<ApplicationUser, IdentityRole>(options => {
                options.Password.RequireDigit = true;
                options.Password.RequiredLength = 8;
                options.Password.RequireNonAlphanumeric = true;
                options.Password.RequireUppercase = false;
                options.Password.RequireLowercase = false;
            })
              .AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
            #region Services
            services.AddTransient<IAccountService, AccountService>();
            services.AddTransient<IFileService, FileService>();
            #endregion

            services.Configure<JWTSettings>(configuration.GetSection("JWTSettings"));

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            })
      .AddJwtBearer(o =>
      {
          o.RequireHttpsMetadata = false;
          o.SaveToken = false;
          o.TokenValidationParameters = new TokenValidationParameters
          {
              ValidateIssuerSigningKey = true,
              ValidateIssuer = true,
              ValidateAudience = true,
              ValidateLifetime = true,
              ClockSkew = TimeSpan.Zero,
              ValidIssuer = configuration["JWTSettings:Issuer"],
              ValidAudience = configuration["JWTSettings:Audience"],
              IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jWTSettingsKey))
          };
      });
            

            #endregion

        }

我已经尝试更改 cors 配置,允许所有原点。我还在 Azure 中配置了 CORS(启用 Access-Control-Allow-Credentials) 我还尝试在 Azure 中配置 API 管理器,但我不确定是否有必要,并且我必须与客户协商。

asp.net Azure JWT 标识 http-status-code-401

评论


答: 暂无答案