在 asp.net 核心中使用身份时未找到具有授权属性的操作

Posted

技术标签:

【中文标题】在 asp.net 核心中使用身份时未找到具有授权属性的操作【英文标题】:Not Found for actions with Authorize attribute while using identity in asp.net core 【发布时间】:2021-12-22 09:30:44 【问题描述】:

正如我在标题中提到的,当我将 Identity 添加到我的 ASP.Net Core Web API 项目时,对于上面具有 Authorize 属性的操作,我会收到 NotFound 错误。 我检查了这个question,但我仍然不知道我在哪里做错了。

为了简单起见,我创建了这个控制器:

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase

    [Authorize(Roles = "test")]
    public ActionResult<string> Get(string name)
    
        return Ok($"Hello name");
    

这是我在 Startup.cs 中的代码:

public void ConfigureServices(IServiceCollection services)

    services.AddDbContext<ApplicationDbContext>(options =>
    
        options.UseSqlServer(Configuration.GetConnectionString("SqlServer"));
    );
    services.AddControllers();

    services.AddAuthentication(options =>
    
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    )
    .AddJwtBearer(options =>
    
        var secretKey = Encoding.UTF8.GetBytes(settings.SecretKey);
        var encriptionKey = Encoding.UTF8.GetBytes(settings.EncriptKey);

        options.TokenValidationParameters = new TokenValidationParameters()
        
            ClockSkew = TimeSpan.FromMinutes(settings.ClockSkewMinutes),
            IssuerSigningKey = new SymmetricSecurityKey(secretKey),
            TokenDecryptionKey = new SymmetricSecurityKey(encriptionKey),
            // some other options
        ;

        options.IncludeErrorDetails = false;
        options.RequireHttpsMetadata = true;
        options.SaveToken = true;
    );

    /* When I remove this code then it works */
    services.AddIdentity<User, Role>(options =>
    
        // options
    ).AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

    // ...

    app.UseRouting();
    app.UseHttpsRedirection();

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

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

更多信息:

当我从操作上方的 Authorize 属性中删除 Role 属性时,它会起作用 当我删除 AddIdentity 时,它可以工作。

【问题讨论】:

【参考方案1】:

这个问题有两个原因,至少我知道其中2个:


没有定义DefaultChallengeScheme

使用

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).
         .AddJwtBearer

而不是使用

services.AddAuthentication(options =>

    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; // < this is the key
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
)
.AddJwtBearer

您必须定义DefaultChallengeScheme 属性,该属性被IAuthenticationService.ChallengeAsync() 用作默认方案

挑战指定的认证方案。身份验证 当未经身份验证的用户请求 需要身份验证的端点。


添加订单

(您的错误)添加服务的顺序很重要。在这里,您首先添加JWT,然后添加Identity,这将覆盖您在JWT 中所做的设置。您可以在末尾添加JWT

----------------------------------------------- -----------------------

并覆盖您可以使用的操作的默认设置

[Authorize(Roles = "admin", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

[Authorize(Roles = "admin", AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]

【讨论】:

以上是关于在 asp.net 核心中使用身份时未找到具有授权属性的操作的主要内容,如果未能解决你的问题,请参考以下文章

Asp.net核心身份声明与基于角色的授权[重复]

如何在 ASP.net 核心集成测试中获得授权(我非常接近)

使用 ASP.NET 核心 MVC/Razor 站点和 WebAPI 进行授权

关于 ASP.NET Core 中的授权

在 ASP.NET 核心应用中本地模拟 Azure 应用服务授权

将 ASP.NET 核心身份用户属性保存在另一个表中