使用UseJwtBearerAuthentication中间件的自定义401和403响应模型 [英] Custom 401 and 403 response model with UseJwtBearerAuthentication middleware

查看:303
本文介绍了使用UseJwtBearerAuthentication中间件的自定义401和403响应模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当401和403出现时,我想使用JSON响应模型进行响应.例如:

I want to respond with a JSON response model when a 401 and 403 occur. For example:

HTTP 401
{
  "message": "Authentication failed. The request must include a valid and non-expired bearer token in the Authorization header."
}

我正在使用中间件(如此答案中所述) 404s并能很好地工作,但401或403s并非如此.这是中间件:

I am using middleware (as suggested in this answer) to intercept 404s and it works great, but it is not the case with 401 or 403s. Here is the middleware:

app.Use(async (context, next) =>
{
    await next();
    if (context.Response.StatusCode == 401)
    {
        context.Response.ContentType = "application/json";
        await context.Response.WriteAsync(JsonConvert.SerializeObject(UnauthorizedModel.Create(), SerializerSettings), Encoding.UTF8);
    }
});

当放在Startup.Configure(..)中的app.UseJwtBearerAuthentication(..)下方时,它似乎被完全忽略了,并返回了正常的401.

When placed BELOW app.UseJwtBearerAuthentication(..) in Startup.Configure(..), it seems to be completely ignored and a normal 401 is returned.

Startup.Configure(..)中放置在app.UseJwtBearerAuthentication(..)上方时,将引发以下异常:

When placed ABOVE app.UseJwtBearerAuthentication(..) in Startup.Configure(..), then the following exception is thrown:

连接ID"0HKT7SUBPLHEM":引发了未处理的异常 应用程序. System.InvalidOperationException:标头是 只读,响应已经开始.在 Microsoft.AspNetCore.Server.Kestrel.Internal.Http.FrameHeaders.Microsoft.AspNetCore.Http.IHeaderDictionary.set_Item(String 键,StringValues值) Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.set_ContentType(String 值)在MyProject.Api.Startup.< b__12_0> d.MoveNext()中 Startup.cs

Connection id "0HKT7SUBPLHEM": An unhandled exception was thrown by the application. System.InvalidOperationException: Headers are read-only, response has already started. at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.FrameHeaders.Microsoft.AspNetCore.Http.IHeaderDictionary.set_Item(String key, StringValues value) at Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.set_ContentType(String value) at MyProject.Api.Startup.<b__12_0>d.MoveNext() in Startup.cs

推荐答案

设置是正确的,但是实际上不需要创建自己的中间件,因为您可以利用事件模型来覆盖默认的质询逻辑.

Set was on the right track, but there's actually no need to create your own middleware, as you can leverage the events model to override the default challenge logic.

下面是一个示例,该示例将以纯文本形式返回包含OAuth2错误代码/说明的401响应(您当然可以返回JSON或所需的任何内容):

Here's an example that will return a 401 response containing the OAuth2 error code/description as plain text (you can of course return JSON or whatever you want):

app.UseJwtBearerAuthentication(new JwtBearerOptions
{
    Authority = "http://localhost:54540/",
    Audience = "http://localhost:54540/",
    RequireHttpsMetadata = false,
    Events = new JwtBearerEvents
    {
        OnChallenge = async context =>
        {
            // Override the response status code.
            context.Response.StatusCode = 401;

            // Emit the WWW-Authenticate header.
            context.Response.Headers.Append(
                HeaderNames.WWWAuthenticate,
                context.Options.Challenge);

            if (!string.IsNullOrEmpty(context.Error))
            {
                await context.Response.WriteAsync(context.Error);
            }

            if (!string.IsNullOrEmpty(context.ErrorDescription))
            {
                await context.Response.WriteAsync(context.ErrorDescription);
            }

            context.HandleResponse();
        }
    }
});

或者,您也可以使用状态代码页中间件,但是对于403响应,您不会对导致它的授权策略有任何提示:

Alternatively, you can also use the status code pages middleware, but for 403 responses, you won't have any hint about the authorization policy that caused it:

app.UseStatusCodePages(async context =>
{
    if (context.HttpContext.Request.Path.StartsWithSegments("/api") &&
       (context.HttpContext.Response.StatusCode == 401 ||
        context.HttpContext.Response.StatusCode == 403))
    {
        await context.HttpContext.Response.WriteAsync("Unauthorized request");
    }
});

这篇关于使用UseJwtBearerAuthentication中间件的自定义401和403响应模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆