401と403が発生したときにJSON応答モデルで応答したい。例えば:
_HTTP 401
{
"message": "Authentication failed. The request must include a valid and non-expired bearer token in the Authorization header."
}
_
私はミドルウェアを使用して( この回答 で提案されているように)404をインターセプトし、それはうまく機能しますが、401または403には当てはまりません。ミドルウェアは次のとおりです。
_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);
}
});
_
app.UseJwtBearerAuthentication(..)
のStartup.Configure(..)
の下に配置すると、完全に無視されているように見え、通常の401が返されます。
app.UseJwtBearerAuthentication(..)
のABOVEStartup.Configure(..)
に配置すると、次の例外がスローされます。
接続ID「0HKT7SUBPLHEM」:未処理の例外がアプリケーションによってスローされました。 System.InvalidOperationException:ヘッダーは読み取り専用であり、応答はすでに開始されています。 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)atMyProject。 Startup.csのApi.Startup。<b__12_0> d.MoveNext()
セットは正しい方向に進んでいましたが、イベントモデルを利用してデフォルトのチャレンジロジックをオーバーライドできるため、実際には独自のミドルウェアを作成する必要はありません。
これは、OAuth2エラーコード/説明をプレーンテキストとして含む401応答を返す例です(もちろん、JSONまたは必要なものを返すことができます)。
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応答の場合、それを引き起こした承認ポリシーについてのヒントはありません。
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");
}
});