API 班级:"Endpoint ... contains authorization metadata, but a middleware was not found that supports authorization."

API call: "Endpoint ... contains authorization metadata, but a middleware was not found that supports authorization."

我目前正致力于在 angular 中创建一个简单的 Web 应用程序,使用 Auth0 来卸载授权部分。现在我正在尝试连接前端部分和后端部分,但遇到了一些麻烦。

出于某种原因,当我向 API 发送 https 请求时,它一直在 chrome 控制台中给我以下错误。

所以我去使用 postman 尝试访问 api。我克服了 CORS 部分错误,而是 het Endpoint .... contains authorization metadata, but a middleware was not found that supports authorization.

这是我的初创公司 class 在我的后端中的样子:

public class Startup
{
    readonly string MyAllowSpecificOrigins = "localhost_origin";

    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)
    {
        string domain = $"https://{Configuration["Auth0:Domain"]}/";
        services.AddControllers();

        // 1. Add Authentication Services
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
            options.Authority = domain;
            options.Audience = Configuration["Auth0:ApiIdentifier"];
            options.TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = ClaimTypes.NameIdentifier
            };
        });

        services.AddAuthorization(options =>
        {
            options.AddPolicy("read:messages", policy => policy.Requirements.Add(new HasScopeRequirement("read:messages", domain)));
        });

        services.AddSingleton<IAuthorizationHandler, HasScopeHandler>();

        services.AddCors(options =>
        {
            options.AddPolicy(name: MyAllowSpecificOrigins,
                builder =>
                {
                    builder.WithOrigins("https://localhost:4200").AllowAnyMethod().AllowAnyHeader();
                });
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }



        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseCors();
        app.UseAuthentication();
        //app.UseAuthorization();

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


    }
}

这是我在 api 上调用的测试控制器:

[Route("api")]
public class TestController : Controller
{
    [HttpGet]
    [Route("private")]
    [Authorize]
    public IActionResult Private()
    {
        return Json(new
        {
            Message = "Hello from a private endpoint! You need to be authenticated to see this."
        });
    }
}

我已阅读文档并遵循 auth0 网站上的示例来实现这一点。我完全找不到哪里出错了。

对于可能 运行 遇到类似问题的人来说,没问题。它最终成为 startup.cs 文件中事物顺序的问题,并使我的本地主机源使用 http 而不是 https。我无法从教程文章中推断出这一点,因为他们省略了很多代码。我最终不得不下载示例项目并逐行比较。这是对我有用的最终 startup.cs 文件:

public class Startup
{
    readonly string MyAllowSpecificOrigins = "localhost_origin";

    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)
    {
        string domain = $"https://{Configuration["Auth0:Domain"]}/";
        services.AddControllers();

        services.AddCors(options =>
        {
            options.AddPolicy(name: MyAllowSpecificOrigins,
                builder =>
                {
                    builder
                        .WithOrigins("http://localhost:4200")
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials();
                });
        });

        // 1. Add Authentication Services
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
            options.Authority = domain;
            options.Audience = Configuration["Auth0:ApiIdentifier"];
            options.TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = ClaimTypes.NameIdentifier
            };
        });

        services.AddAuthorization(options =>
        {
            options.AddPolicy("read:messages", policy => policy.Requirements.Add(new HasScopeRequirement("read:messages", domain)));
        });

        services.AddSingleton<IAuthorizationHandler, HasScopeHandler>();


    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseCors(MyAllowSpecificOrigins);

        app.UseAuthentication();

        app.UseAuthorization();

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


    }