首页 新闻 会员 周边

ASP.NET Core Web API 项目在返回 Forbid 报错 "there was no DefaultForbidScheme found"

0
悬赏园豆:30 [待解决问题]

ASP.NET Core Web API 项目在 Controller Action 中 return Forbid() 时报错 "No authenticationScheme was specified, and there was no DefaultForbidScheme found"

错误日志如下:

System.InvalidOperationException: No authenticationScheme was specified, and there was no DefaultForbidScheme found. The default schemes can be set using either AddAuthentication(string defaultScheme) or AddAuthentication(Action<AuthenticationOptions> configureOptions).
   at Microsoft.AspNetCore.Authentication.AuthenticationService.ForbidAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Mvc.ForbidResult.ExecuteResultAsync(ActionContext context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultFilters>g__Awaited|27_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at NSwag.AspNetCore.Middlewares.SwaggerUiIndexMiddleware.Invoke(HttpContext context)
   at NSwag.AspNetCore.Middlewares.RedirectToIndexMiddleware.Invoke(HttpContext context)
   at NSwag.AspNetCore.Middlewares.OpenApiDocumentMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

请问如何解决?

问题补充:

加上 default scheme 问题依旧

services.AddAuthentication(options =>
{
    options.DefaultScheme = "cnblogs";
    options.DefaultForbidScheme = "cnblogs";
});
dudu的主页 dudu | 高人七级 | 园豆:31003
提问于:2022-06-10 07:35
< >
分享
所有回答(2)
0

找到了一种解决方法,使用 ProblemDetails

return Problem(statusCode: 403);
dudu | 园豆:31003 (高人七级) | 2022-06-10 08:15

找到了更简单的解决方法

return StatusCode(403);
支持(0) 反对(0) dudu | 园豆:31003 (高人七级) | 2022-06-11 20:20
1

Forbid()方法会寻找AuthenticationScheme来决定如何返回403响应(如cookie认证策略Forbid()时会重定向到配置好的登录页面),这个异常可能是没有设置默认的AuthenticationScheme导致的,webapi如果用了JWT认证那么应该设置DefaultAuthenticationSchemeJwtBearerDefaults.AuthenticationScheme同时调用AddJwtBearer注册相关的服务,如果使用了Cookie认证,那么就是CookieAuthenticationDefaults.AuthenticationScheme然后调用AddCookie

// jwt
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(...);
// or cookie
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
. AddCookie(...);

如果在没有配置使用身份认证的情况,返回Problem应该是个不错的方案;如果不想服务有身份认证,又想在Controller中用Forbid(),那么就仅在注册服务时注册身份认证相关服务,中间件配置中不调用app.UseAuthentication();app.UseAuthorization();就行

Laggage | 园豆:878 (小虾三级) | 2022-06-10 13:33

试了 pp.UseAuthentication();app.UseAuthorization(); ,问题依旧

支持(0) 反对(0) dudu | 园豆:31003 (高人七级) | 2022-06-11 19:57

根源是 ForbidResult 的实现中调用了 httpContext.ForbidAsync(详见 ForbidResult.cs#L116),这个设计有问题,我记得以前好像不是怎么设计的,ForbidResult 老老实实返回 403 状态就行了,如果要执行 httpContext.ForbidAsync ,在 middleware 中处理。

知道了这个原因,解决起来就容易了,本来就是想返回个 403 状态码,直接 return StatusCode(403);

支持(0) 反对(0) dudu | 园豆:31003 (高人七级) | 2022-06-11 20:19
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册