具有策略要求抛出的授权属性:不接受以下身份验证方案

Authorize attribute with policy requirement throwing: The following authentication scheme was not accepted

我有这个简单的策略要求设置。我假设这应该 return 401 但它抛出异常

Startup.cs

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.ConfigureAuthorization(options =>
        {
            var policyBuilder = new AuthorizationPolicyBuilder();                
            policyBuilder.AddRequirements(new MyPolicyRequirement());
            options.AddPolicy("MyPolicy", policyBuilder.Build());
        });
        services.AddMvc();            
    }

    // Configure is called after ConfigureServices is called.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        //app.UseErrorPage();            
        app.UseStaticFiles();            
        app.UseMvc();           
    }
}

MyPolicyRequirement.cs

public class MyPolicyRequirement : AuthorizationHandler<MyPolicyRequirement>, IAuthorizationRequirement
{
    protected override void Handle(AuthorizationContext context, MyPolicyRequirement requirement)
    {            
        if (!context.User.HasClaim(c => c.Type == "yes"))
        {
            context.Fail();
            return;
        }

        context.Succeed(requirement);                 
    }
}

ValuesController.cs

[Route("api/[controller]")]
public class ValuesController : Controller
{
    [Authorize(Policy = "MyPolicy")]
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }        
}

据我了解,此流程是您注册一个授权策略,然后将其与授权属性一起使用,然后在控制器上执行该方法之前将对此进行检查,但这并没有发生,而是我我收到此异常

异常

System.InvalidOperationException
The following authentication scheme was not accepted: 
at Microsoft.AspNet.Http.Authentication.Internal.DefaultAuthenticationManager.<ChallengeAsync>d__10.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Mvc.ChallengeResult.<ExecuteResultAsync>d__14.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Mvc.Core.FilterActionInvoker.<InvokeResultAsync>d__53.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Mvc.Core.FilterActionInvoker.<InvokeAsync>d__41.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Mvc.MvcRouteHandler.<InvokeActionAsync>d__7.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Mvc.MvcRouteHandler.<RouteAsync>d__6.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Mvc.Routing.InnerAttributeRoute.<RouteAsync>d__10.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Routing.RouteCollection.<RouteAsync>d__9.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Builder.RouterMiddleware.<Invoke>d__4.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Hosting.Internal.HostingEngine.<>c__DisplayClass29_0.<<Start>b__0>d.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Loader.IIS.RuntimeHttpApplication.<ProcessRequestAsyncImpl>d__13.MoveNext() 
--- exception rethrown --- 
at Microsoft.AspNet.Loader.IIS.RuntimeHttpApplication.<ProcessRequestAsyncImpl>d__13.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Loader.IIS.HttpApplicationBase.<InvokeProcessRequestAsyncImpl>d__9.MoveNext()

看起来你是一堆授权片,但是没有认证中间件,所以系统不知道授权失败时应该做什么。

return 状态代码取决于您选择的身份验证中间件。如果您选择不记名令牌,那么假设中间件是正确的,您将得到 401 返回。如果您选择 cookie 身份验证,您会得到 302 返回,因为它针对浏览器并试图重定向到您的登录页面。

例如,如果在您的 Configure() 中添加

app.UseCookieAuthentication(options =>
{
    options.AuthenticationScheme = "Cookie";
    options.LoginPath = new PathString("/Account/Unauthorized/");
    options.AccessDeniedPath = new PathString("/Account/Forbidden/");
    options.AutomaticAuthentication = true;
});

当您进行身份验证时,您可能会看到重定向到 /Account/Unauthorized。