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# AuthorizeAttribute返回ASP.net Core中的自定义值(无覆盖)_C#_Asp.net Core - Fatal编程技术网

C# AuthorizeAttribute返回ASP.net Core中的自定义值(无覆盖)

C# AuthorizeAttribute返回ASP.net Core中的自定义值(无覆盖),c#,asp.net-core,C#,Asp.net Core,我正在使用ASP.NETCore5.0并制作一个RESTAPI。 我还使用JWT令牌进行身份验证 [授权] 公共类登录控制器:控制器 我已经为JWT添加了授权/认证中间件。如果身份验证失败,如何让AuthorizeAttribute返回自定义值?目前,它是这样做的: Authorize Good token: nothing Authorize Bad token: Return status 401/403 但我希望它能像这样做,返回200 OK,但正文中有JSON响应,因为需要与我的其他

我正在使用ASP.NETCore5.0并制作一个RESTAPI。 我还使用JWT令牌进行身份验证

[授权]
公共类登录控制器:控制器
我已经为JWT添加了授权/认证中间件。如果身份验证失败,如何让AuthorizeAttribute返回自定义值?目前,它是这样做的:

Authorize Good token: nothing
Authorize Bad token: Return status 401/403
但我希望它能像这样做,返回200 OK,但正文中有JSON响应,因为需要与我的其他响应保持一致,并且对浏览器友好

Authorize Good token: nothing
Authorize Bad token: 200 OK <json>

注意:我已经创建了自定义身份验证策略。我只需要它返回一个我不知道怎么做的唯一值。好吧,这不是很漂亮(就其位置而言),但应该可以正常工作:

.AddJwtBearer(选项=>
{
// ...
options.Events=newjwtbearerevents()
{
OnAuthenticationFailed=ctx=>
ctx.Response.WriteAsJsonAsync(新的
{
成功=错误,
statusCode=您的状态代码,
response=yourStringArray
})
};
// ...
}

您可能已经了解了要点。您可以为各种JWT令牌身份验证事件设置处理程序。
WriteAsJsonAsync()
自动设置200个状态代码和applicaton/json内容类型。但您也可以使用
WriteAsync()编写字符串
,并设置自定义状态代码和内容类型。

这里是另一个解决方案,尝试遵循横切关注点的模式。使用此解决方案,我们当然不必为每个身份验证方案重复代码

首先,您不能在此场景中使用
iaauthorizationfilter
IAsyncAuthorizationFilter
,因为所有筛选器都是按顺序执行的,并且不能确保顺序是确定的(通常在策略组合步骤中,所有
authorizationfilter
都附加在所有其他筛选器之后)。因此,在运行筛选器时,结果可能尚未设置,您甚至不知道授权是成功还是失败。您也不能使用
IResultFilter
IAsyncResultFilter
,因为如果在运行授权筛选器之后设置了一些
result
,则结果筛选器将被运行

幸运的是,我们有一种过滤器总是在这种情况下运行。那就是
IAlwaysRunsultFilter
IAsyncalwaysRunsultFilter
。因此,您可以添加一个此类过滤器并覆盖结果,如下所示:

public class CustomAsyncAlwaysRunResultFilterAttribute : Attribute, IAsyncAlwaysRunResultFilter
{
    public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
    {
        if (context.HttpContext.Response.StatusCode == 403 ||
            context.Result is ForbidResult)
        {
            //set the result of your choice
            context.Result = new JsonResult(new { ... });
        }
        await next();            
    }
}
result
(如果设置)中,您可以访问身份验证方案列表(如果为空,则使用默认方案),这可能会有所帮助。 请注意,
禁止结果
可以由一个
授权筛选器
或您的一个自定义筛选器设置。但是,如果您的自定义筛选器设置了不同类型的结果,则上面的代码对此一无所知,可能不容易知道如何处理。如果您rite加入授权请求的其他自定义授权筛选器

最后,如果您使用授权中间件(自
asp.net core 3.0
以来作为一个单独的中间件引入),我怀疑您能否实现
IAAuthorizationMiddleWareResultHandler
来拦截和覆盖那里的结果。但是,我没有用这种方法进行测试(而且从未尝试过).但我将其包含在这里,供您自己尝试(如果您告诉我您尝试的结果,无论是否有效,那将非常好):


我可以针对不同的策略做出不同的响应吗?或者不可以?啊,我想你的意思是作为一个交叉关注点。我现在在文档中读到“即使身份验证失败也会调用授权处理程序”,所以我认为这应该是可能的。但不幸的是,现在已经太晚了,所以我明天必须研究它(并编辑答案)。当然,希望同时有其他人会回答,或者也许你能让它工作。是的,它确实工作了。除了身份验证失败之外,这是一个挑战。它也适用于OnForbidden的自定义策略。但是,它不能在两个不同的自定义策略之间生成不同的响应,我现在对此很满意因为我只使用了一个。
public class CustomAsyncAlwaysRunResultFilterAttribute : Attribute, IAsyncAlwaysRunResultFilter
{
    public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
    {
        if (context.HttpContext.Response.StatusCode == 403 ||
            context.Result is ForbidResult)
        {
            //set the result of your choice
            context.Result = new JsonResult(new { ... });
        }
        await next();            
    }
}
public class CustomAuthorizationMiddlewareResultHandler : IAuthorizationMiddlewareResultHandler {
   public Task HandleAsync (RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult){
       //here you have access to the AuthorizationPolicy
       //but note that the policy contains no name (as added in the configuration)
       //it's kind of combined set of authentication schemes & handlers.
   }
}