添加 Authorize 属性时 Web api 核心返回 404

Posted

技术标签:

【中文标题】添加 Authorize 属性时 Web api 核心返回 404【英文标题】:Web api core returns 404 when adding Authorize attribute 【发布时间】:2019-02-01 22:01:23 【问题描述】:

我是 .net 核心的新手,我正在尝试创建实现 jwt 以进行身份​​验证和授权的 web api 核心。

在 Startup 类中我是这样配置的:

public class Startup

    public Startup(IConfiguration configuration)
    
        Configuration = configuration;
    

    public IConfiguration Configuration  get; 

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    

        services.AddDbContext<MandarinDBContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("MyConnection")));

        services.AddIdentity<User, Role>()
        .AddEntityFrameworkStores<MyDBContext>()
        .AddDefaultTokenProviders();

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                
                    options.TokenValidationParameters = new TokenValidationParameters
                    
                        ValidateIssuer = false,
                        ValidateAudience = false,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = "yourdomain.com",
                        ValidAudience = "yourdomain.com",
                        IssuerSigningKey = new SymmetricSecurityKey(
                            Encoding.UTF8.GetBytes("My secret goes here"))
                    ;

                    options.RequireHttpsMetadata = false;
                );

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        // Add application services.
        services.AddTransient<IUserService, UserService>();
    

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    
        if (env.IsDevelopment())
        
            app.UseDeveloperExceptionPage();
        
        else
        
            app.UseHsts();
        

        app.UseHttpsRedirection();

        app.UseAuthentication();
        app.UseMvc();
    

但是当我尝试调用以下操作时:

    [Authorize]
    [HttpGet]
    [Route("api/Tokens")]
    public IActionResult TestAuthorization()
    
        return Ok("You're Authorized");
    

我得到 404 未找到。如果我删除 Authorize 属性它正在工作。

你能指导我解决这个问题吗?

【问题讨论】:

也许这可以说明一些问题:github.com/openiddict/openiddict-core/issues/498 如果你有 cookie authentication 可能会将你重定向到一个 Not Found 页面,没有它你只会得到一个不错的 401 - 此请求的授权已被拒绝。跨度> 【参考方案1】:

当您的 API 未经授权且您的重定向 URL 不存在时,就会发生这种情况。 当身份验证失败时,Web API 将发送一个 401 代码。现在,如果您在客户端处理此代码并为授权失败执行重定向,请确保重定向的 Url 存在。 此外,请勿将 [Authorize] 属性添加到处理身份验证方法(登录/注册)的控制器。 您的罪魁祸首似乎是 Authorize 属性。由于您使用的是 JWT 身份验证方案。您的授权属性应遵循

    [Authorize(AuthenticationSchemes = "Bearer")]
    [HttpGet]
    [Route("api/Tokens")]
    public IActionResult TestAuthorization()
    
        return Ok("You're Authorized");
    

要使其成为默认身份验证方案,请将 AddIdentity 更改为 AddIdentityCore。这是一篇非常好的文章。

Using JwtBearer Authentication in an API-only ASP.NET Core Project

【讨论】:

不,我没有在客户端处理它我正在使用 postMan 测试它 options.AccessDeniedPath = "/Identity/Account/AccessDenied";您在 startup.cs 中的配置服务代码中是否有类似的内容 不,我没有这样的配置,我正在使用有效的 jwt 令牌测试我的端点 非常感谢它现在正在工作。但是我有一个问题,我可以在每次需要指定 Authorize 属性时配置它而不需要提供 AuthenticationSchemes 参数吗?【参考方案2】:

当您使用 JwtBearer 令牌时,您可以将此 sn-p 添加到您的 ConfigureServices:

  services.AddControllers(opt => 
            var policy = new AuthorizationPolicyBuilder("Bearer").RequireAuthenticatedUser().Build();
            opt.Filters.Add(new AuthorizeFilter(policy));
        )

这将在整个应用程序中设置承载身份验证策略,并要求每个端点上都经过身份验证的用户。 此外,您不需要将 [Authorize] 放在方法上,如果您希望未经身份验证的用户可以使用端点和控制器,可以将 [AllowAnonymous] 放在端点和控制器上。

注意:这适用于 .net core 3.1

【讨论】:

虽然这确实有效,但我最终使用了接受的答案,因为当我需要使用 Roles 覆盖和指定授权属性时,我无法让它工作。【参考方案3】:

我遇到了和你一样的问题,我通过修改ConfigureServices设法解决了

从这里

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(..)

到这里

services.AddAuthentication(options => 
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;)
 .AddJwtBearer(...);

【讨论】:

【参考方案4】:

它只使用授权属性对我有用

[Authorize]
    public class WeatherForecastController : ControllerBase
    ...

通过这种方式在 ConfigureServices 中

services.AddIdentity<ApplicationUser, ApplicationRole>(options => options.SignIn.RequireConfirmedAccount = true)
               .AddEntityFrameworkStores<OkazContext>();

            var key = Encoding.ASCII.GetBytes(Configuration["JwtConfig:Secret"]);

            var tokenValidationParams = new TokenValidationParameters
            
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidateIssuer = false,
                ValidateAudience = false,
                ValidateLifetime = true,
                RequireExpirationTime = false,
                ClockSkew = TimeSpan.Zero
            ;

            services.AddSingleton(tokenValidationParams);

            services.AddAuthentication(options => 
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            )
            .AddJwtBearer(jwt => 
                jwt.SaveToken = true;
                jwt.TokenValidationParameters = tokenValidationParams;
            );

【讨论】:

以上是关于添加 Authorize 属性时 Web api 核心返回 404的主要内容,如果未能解决你的问题,请参考以下文章

在 .net 核心 Web API 中自动添加策略属性

身份服务器如何在 API 或我们使用 Authorize 属性时验证令牌?

如何使 ASP.NET Web API 正确响应 403 或 401?

在预检OPTION调用后获得401 Unauthorized

如何在 ASP.NET Core Web API 中添加两个不同的令牌

使用 Postman 进行 ASP.NET Web API 授权