缺少令牌时更改来自 OpenIdDict 验证的响应代码
Change response code from OpenIdDict validation when token is missing
我使用 OpenIddict 3.0 进行不记名令牌身份验证。当客户端访问缺少令牌的授权控制器时,我希望它 return 错误代码 401 Unauthorized not 400 Bad Request.
这是错误消息的来源,但是 http 状态代码是从哪里来的,我该如何覆盖它?
OpenIddictValidationHandlers.cs
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (string.IsNullOrEmpty(context.Request.AccessToken))
{
context.Logger.LogError("The request was rejected because the access token was missing.");
context.Reject(
error: Errors.InvalidRequest,
description: "The access token is missing.");
return default;
}
context.Token = context.Request.AccessToken;
return default;
}
还有我的Startup.cs
...
var openId = services.AddOpenIddict()
...
.AddValidation(config =>
{
config.UseLocalServer();
config.UseAspNetCore();
});
感谢您报告此问题,该问题已在 3.0.0-alpha1.20163.83
版本中修复:OpenIddict 现在将 return 因缺少访问令牌而拒绝请求的 401 错误。
负责选择适当的 HTTP 状态代码的事件处理程序位于 OpenIddict.Validation.AspNetCore
:
/// <summary>
/// Contains the logic responsible of attaching an appropriate HTTP status code.
/// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core.
/// </summary>
public class AttachHttpResponseCode<TContext> : IOpenIddictValidationHandler<TContext> where TContext : BaseRequestContex
{
/// <summary>
/// Gets the default descriptor definition assigned to this handler.
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpRequest>()
.UseSingletonHandler<AttachHttpResponseCode<TContext>>()
.SetOrder(AttachCacheControlHeader<TContext>.Descriptor.Order - 1_000)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Response == null)
{
throw new InvalidOperationException("This handler cannot be invoked without a response attached.");
}
// This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetHttpRequest()?.HttpContext.Response;
if (response == null)
{
throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved.");
}
response.StatusCode = context.Response.Error switch
{
null => 200,
Errors.InvalidToken => 401,
Errors.MissingToken => 401,
Errors.InsufficientAccess => 403,
Errors.InsufficientScope => 403,
_ => 400
};
return default;
}
}
我使用 OpenIddict 3.0 进行不记名令牌身份验证。当客户端访问缺少令牌的授权控制器时,我希望它 return 错误代码 401 Unauthorized not 400 Bad Request.
这是错误消息的来源,但是 http 状态代码是从哪里来的,我该如何覆盖它?
OpenIddictValidationHandlers.cs
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (string.IsNullOrEmpty(context.Request.AccessToken))
{
context.Logger.LogError("The request was rejected because the access token was missing.");
context.Reject(
error: Errors.InvalidRequest,
description: "The access token is missing.");
return default;
}
context.Token = context.Request.AccessToken;
return default;
}
还有我的Startup.cs
...
var openId = services.AddOpenIddict()
...
.AddValidation(config =>
{
config.UseLocalServer();
config.UseAspNetCore();
});
感谢您报告此问题,该问题已在 3.0.0-alpha1.20163.83
版本中修复:OpenIddict 现在将 return 因缺少访问令牌而拒绝请求的 401 错误。
负责选择适当的 HTTP 状态代码的事件处理程序位于 OpenIddict.Validation.AspNetCore
:
/// <summary>
/// Contains the logic responsible of attaching an appropriate HTTP status code.
/// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core.
/// </summary>
public class AttachHttpResponseCode<TContext> : IOpenIddictValidationHandler<TContext> where TContext : BaseRequestContex
{
/// <summary>
/// Gets the default descriptor definition assigned to this handler.
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpRequest>()
.UseSingletonHandler<AttachHttpResponseCode<TContext>>()
.SetOrder(AttachCacheControlHeader<TContext>.Descriptor.Order - 1_000)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Response == null)
{
throw new InvalidOperationException("This handler cannot be invoked without a response attached.");
}
// This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetHttpRequest()?.HttpContext.Response;
if (response == null)
{
throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved.");
}
response.StatusCode = context.Response.Error switch
{
null => 200,
Errors.InvalidToken => 401,
Errors.MissingToken => 401,
Errors.InsufficientAccess => 403,
Errors.InsufficientScope => 403,
_ => 400
};
return default;
}
}