如何不被迫在操作的 [Authorize] 属性上添加 AuthenticationSchemes

问题描述 投票:0回答:1

我是 ASP.NET Core 的初学者,特别是 ASP.NET Core 6.0。我尝试按照教程在我当前的 Web API(not minimal)项目中设置 Identity + JWT 身份验证和授权,尽管到目前为止它可以使用基本登录/注册,但有一件事困扰我,我还没有找到在教程或任何 SO 问题中回答。

我必须在每个控制器操作的

AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme
属性中添加
[Authorize(...)]
,否则它们都会返回 404 空结果,即使具有正确的身份验证 + 授权(如果有)。

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using FluentValidation;

using Capstone.ExceptionHandling;
using Capstone.Data;
using Capstone.Models;
using Capstone.Features;
using Capstone.Features.ApplicantModule;
using Capstone.Features.EmployeeModule;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Capstone.Features.Auth;
using Capstone.Features.Auth.Models;

var builder = WebApplication.CreateBuilder(args);

// ... irrelevant

// ---- Auth ----
builder.Services
    .AddAuthentication(options =>
    {
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateIssuerSigningKey = true,
            ValidateLifetime = true,
            ValidIssuer = builder.Configuration.GetSection("JWT:ValidIssuer").Value,
            ValidAudience = builder.Configuration.GetSection("JWT:ValidAudience").Value,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
                builder.Configuration.GetSection("JWT:SecretKey").Value
            ))
        };
    });
builder.Services
    .AddIdentity<AuthUser, IdentityRole>(options =>
    {
        options.User.RequireUniqueEmail = true;
        options.Password.RequiredLength = 8;
        options.Password.RequireUppercase = false;
        options.Password.RequireNonAlphanumeric = false;
    })
    .AddEntityFrameworkStores<CapstoneContext>();
builder.Services.AddScoped<IValidator<RegisterRequest>, RegisterRequestValidator>();

// ... irrelevant

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseCors("Capstone");

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

app.MapControllers();

app.Run();

有没有办法在我的项目中全局设置这个?

我已经尝试了在线建议的多个修复程序,例如手动设置

AddAuthentication
选项(
DefaultScheme, DefaultAuthenticationScheme, DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme
)而不是仅仅通过
JwtBearerDefaults.AuthenticationScheme
,并检查我对
Use...
调用的排序,例如保证
UseAuthentication
UseAuthorization之前进行
,虽然这些通常会提到
UseRouting
UseMvc
但我的项目没有那些。

我只是不想在控制器的操作方法的

AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme
属性中提供
[Authorize(...)]

asp.net-core authentication jwt authorization asp.net-core-webapi
1个回答
0
投票

我找到了问题和解决方法,但我不知道真正导致它的原因。

查看控制台时,在发出请求后,您可以看到:

错误: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[9] AuthenticationScheme:Identity.Application 未通过身份验证。

这是我最初的怀疑:配置了另一个默认处理程序。

如果您查看

AddIdentity<TUser, TRole>
的源代码,您将看到以下代码:

// Services used by identity
services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
    options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddCookie(IdentityConstants.ApplicationScheme, o =>
{
    o.LoginPath = new PathString("/Account/Login");
    o.Events = new CookieAuthenticationEvents
    {
        OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
    };
})
/*...*/

这会将 Cookie 配置为默认设置。我试图将 Jwt 配置放在它后面,但无济于事。 cookie 保持默认实现。

但我仍然可以将 Bearer scheme 配置为默认授权策略:

builder.Services
    .AddAuthorization(opt =>
    {
        // Configure the default policy
        opt.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
            .RequireAuthenticatedUser()
            .Build();
    });

这增加了一个全局策略,要求每个请求都通过这个策略。所以你不需要再在任何地方添加

[Authorize]
属性。只需在您的
[AllowAnonymous]
上方放一个
AuthController
,这样人们仍然可以注册。

© www.soinside.com 2019 - 2024. All rights reserved.