Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用ASP.Net核心中的Authorize属性返回HTTP 403_C#_Asp.net Core_Asp.net Core Mvc - Fatal编程技术网

C# 使用ASP.Net核心中的Authorize属性返回HTTP 403

C# 使用ASP.Net核心中的Authorize属性返回HTTP 403,c#,asp.net-core,asp.net-core-mvc,C#,Asp.net Core,Asp.net Core Mvc,在使用ASP.NETWebAPI时,我曾经有一个我将根据情况返回HTTP403或401。e、 g.如果用户未通过身份验证,则返回401;如果用户已通过身份验证,但没有相应的权限,请返回403。在那上面 现在看来,在新的ASP.Net核心中,他们不再支持基于策略的方法。然而,核心MVC似乎受到了与它的前辈相同的“针对所有身份验证错误只返回401”方法的影响 如何覆盖框架以获得所需的行为?我最终使用中间件实现了这一点: public class AuthorizeCorrectlyMiddlewar

在使用ASP.NETWebAPI时,我曾经有一个我将根据情况返回HTTP
403
401
。e、 g.如果用户未通过身份验证,则返回
401
;如果用户已通过身份验证,但没有相应的权限,请返回
403
。在那上面

现在看来,在新的ASP.Net核心中,他们不再支持基于策略的方法。然而,核心MVC似乎受到了与它的前辈相同的“针对所有身份验证错误只返回
401
”方法的影响


如何覆盖框架以获得所需的行为?

我最终使用中间件实现了这一点:

public class AuthorizeCorrectlyMiddleware
{
    readonly RequestDelegate next;

    public AuthorizeCorrectlyMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        await next(context);

        if (context.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
        {
            if (context.User.Identity.IsAuthenticated)
            {
                //the user is authenticated, yet we are returning a 401
                //let's return a 403 instead
                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
            }
        }
    }
}
应该在
启动中注册。在调用
app.UseMvc()之前配置
,在打开一个后,它看起来实际上应该可以工作…某种程度上

在您的
启动.Configure
中,如果您只调用
app.UseMvc()
而不注册任何其他中间件,您将获得
401
中与身份验证相关的任何错误(未经身份验证、已验证但无权限)

但是,如果您注册了一个支持它的身份验证中间件,则未经身份验证的将正确获得
401
,无权限的将正确获得
403
。对我来说,我使用了
jwtbearermiddle软件
,它允许通过身份验证。关键部分是在创建中间件时设置
自动挑战
选项:

public class AuthorizeCorrectlyMiddleware
{
    readonly RequestDelegate next;

    public AuthorizeCorrectlyMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        await next(context);

        if (context.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
        {
            if (context.User.Identity.IsAuthenticated)
            {
                //the user is authenticated, yet we are returning a 401
                //let's return a 403 instead
                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
            }
        }
    }
}
启动中。配置

app.UseJwtBearerAuthentication(new JwtBearerOptions
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true
});
app.UseMvc();
AutomaticAuthenticate
将自动设置
ClaimsPrincipal
,以便您可以在控制器中访问
User
AutomaticChallenge
允许身份验证中间件在发生身份验证错误时修改响应(在这种情况下,适当设置
401
403


如果您有自己的身份验证方案要实现,那么您将继承
AuthenticationMiddleware
AuthenticationHandler
,类似于。

这是我要建议的,但不确定如何仅将其应用于某些控制器/操作,就像使用属性一样。这是危险的,因为在使用next(上下文)调用next middleware/delegate后写入HttpResponse(在本例中通过设置statuscode)如果管道中的其他中间件已经开始写入响应,则将引发异常。忘记提及…。在修改状态码之前,至少应检查context.response.HasStarted==false。根据@blowdart,如果MVC6 Authorize属性在用户经过身份验证但未经授权的情况下仍然返回401而不是403,那么要么是应该提交的错误,要么是您做错了什么。我只是根据设计假设,无论在何种情况下,它都返回401。如果这种行为不是预期的,我将在aspnet/security中提交一个bug。请参阅此处的最后一条评论:我没有使用JWTBeareAuthentication,而是使用cookie auth。设置AutomaticChallenge=true会在授权失败时自动重定向。我不想重定向,但403的。从我在文档中看到的情况来看,这是不可能的。Cookie auth是webforms时代带有“FormsAuthentication”的默认设置。我认为这种行为是模仿这种行为的。e、 g.如果某人未通过身份验证,您希望将其重定向到登录页面,之后将使用其身份验证令牌设置cookie。如果您想要cookieauth和JWT的行为,您可能需要使用
AuthenticationMiddleware
AuthenticationHandler
实现自定义身份验证方案。为我解决了一个大问题。谢谢我们如何在Identity Core 2中使用它?那里没有这样的选择