ASP.NET Core
.NET Framework 中一套用于生成 Web 应用程序和 XML Web 服务的技术。
25 个问题
我有一个这样的自定义身份验证处理程序
public class MyAuthenticationSchemeOptions: AuthenticationSchemeOptions
{
}
public class MyAuthenticationHandler: AuthenticationHandler<MyAuthenticationSchemeOptions>
{
private ICacheProviderService _cacheService;
private readonly IConfiguration _configuration;
public MyAuthenticationHandler(
IOptionsMonitor<MyAuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock,
ICacheProviderService cacheService,
IConfiguration configuration)
: base(options, logger, encoder, clock)
{
_cacheService = cacheService;
_configuration = configuration;
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (!Request.Headers.ContainsKey("Header")){
Context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
//await Context.Response.WriteAsync("request doesn't contains header");
return AuthenticateResult.Fail("request doesn't contains header");
}
//further logic of success
}
public static class AuthenticateExtensions
{
public static AuthenticationBuilder AddAuth(this AuthenticationBuilder builder, Action<GlobalGroupAuthenticationSchemeOptions> configureOptions, string scheme)
{
return builder.AddScheme<MyAuthenticationSchemeOptions, MyAuthenticationHandler>(scheme,"abcd", configureOptions);
}
}
控制器装饰有
[Authorize(AuthenticationSchemes = "MyAuthenticationScheme")]
Startup.cs
ConfigureServices(IServiceCollection services){
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "MyAuthenticationScheme";
options.DefaultChallengeScheme = "MyAuthenticationScheme";
}).AddAuth(x => { }, "MyAuthenticationScheme");
}
Configure(IApplicationBuilder app, IWebHostEnvironment env,ILogger<Startup> logger){
//Other logic is removed as not required here
app.UseRouting();
app.UseAuthorization();
}
此代码仅返回状态代码为“未授权”。如果请求没有标头,则不会返回任何错误消息作为响应。当我取消注释此行的那一刻,我立即收到一个未经处理的异常。任何建议,请在自定义 AuthenticationHandler 服务的情况下返回消息作为响应await Context.Response.WriteAsync("request doesn't contains header");
info: Middleware.MyAuthenticationHandler[7]
MyAuthenticationScheme was not authenticated. Failure message: Authentication Header Not Found
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: StatusCode cannot be set because the response has already started.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowResponseAlreadyStartedException(String value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.set_StatusCode(Int32 value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode(Int32 value)
at Microsoft.AspNetCore.Http.DefaultHttpResponse.set_StatusCode(Int32 value)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.HandleChallengeAsync(AuthenticationProperties properties)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.ChallengeAsync(AuthenticationProperties properties)
at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
warn: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[2]
The response has already started, the error handler will not be executed.
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HM53499HNTTT", Request id "0HM53499HNTTT:00000002": An unhandled exception was thrown by the application.
System.InvalidOperationException: StatusCode cannot be set because the response has already started.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowResponseAlreadyStartedException(String value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.set_StatusCode(Int32 value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode(Int32 value)
at Microsoft.AspNetCore.Http.DefaultHttpResponse.set_StatusCode(Int32 value)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.HandleChallengeAsync(AuthenticationProperties properties)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.ChallengeAsync(AuthenticationProperties properties)
at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.HandleException(HttpContext context, ExceptionDispatchInfo edi)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
Note:此问题总结整理于:Response is null if middleware return AuthenticateResult.Fail()
System.InvalidOperationException:无法设置状态代码,响应已启动。>
根据上面的描述,我有一个建议,您可以在设置 StatusCode 之前检查“响应是否已经开始”: 代码如下所示:
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (!Request.Headers.ContainsKey("Header"))
{
if (!Context.Response.HasStarted)
{
string result;
Context.Response.StatusCode = StatusCodes.Status401Unauthorized;
result = JsonConvert.SerializeObject(new { error = "Request doesn't contains header" });
Context.Response.ContentType = "application/json";
await Context.Response.WriteAsync(result);
}
else
{
await Context.Response.WriteAsync(string.Empty);
}
return AuthenticateResult.Fail("request doesn't contains header");
}
//further logic of success
}
如果答案不能解决您的问题,请提供更多错误的详细信息,以帮助我们追踪正在发生的事情.
希望这对你有所帮助。 如果回复有帮助,请单击“接受答案”并投赞成票。
注意:如果您想接收此线程的相关电子邮件通知,请按照我们文档中的步骤启用电子邮件通知。