Timur2342
@Timur2342

Почему получаю System.InvalidOperationException: No authentication handler is registered for the scheme?

Вызывает ошибку "System.InvalidOperationException: No authentication handler is registered for the scheme 'A company with such a number, website, or phone number exists.'. The registered schemes are: Bearer. Did you forget to call AddAuthentication().Add[SomeAuthHandler]("A company with such a number, website, or phone number exists.",...)?", именно из за того что я возвращаю Forbid.

[ApiController]
[Route("/api/delivery-company")]
public class DeliveryCompanyController(
    ILogger<DeliveryCompanyController> logger,
    DeliveryCompanyService service,
    IMapper mapper)
    : ControllerBase
{
    private readonly ILogger<DeliveryCompanyController> _logger = logger;

    [HttpPost, ValidationFilter, AnonymousOnly]
    public async Task<IActionResult> Create([Required, FromForm] DeliveryCompanyCreateQuery query)
    {
        var phoneNumber = PhoneNumberValueObject.Create(query.PhoneNumber);
        
        if (Uri.TryCreate(query.WebSite, new UriCreationOptions(), out Uri? webSite)
            && phoneNumber is not null)
        {
            var foundCompany = await service.GetByAnyParam(query.Name, webSite, phoneNumber);

            if (foundCompany is not null)
                return Forbid("A company with such a number, website, or phone number exists.");
        
            var newCompany = mapper.Map<DeliveryCompanyEntity>(query);
            await service.Add(newCompany);

            return Ok();
        }
        return BadRequest("Not a valid web site and/or phone number");
    }
}


В Program:
builder.Services.AddAuthentication(auth =>
{
    var defaultAuthSceme = JwtBearerDefaults.AuthenticationScheme;
    
    auth.DefaultAuthenticateScheme = defaultAuthSceme;
    auth.DefaultChallengeScheme = defaultAuthSceme;
}).AddJwtBearer((opts) =>
{
    opts.RequireHttpsMetadata = false;

    opts.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateAudience = false,
        ValidateIssuer = true,
        ValidIssuer = jwtOptions.Issuer,
        ValidAlgorithms = new List<string> { jwtOptions.AlgorithmForAccessToken },
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = jwtOptions.GetAccessSymmetricSecurityKey(),

        ValidateLifetime = true,
        LifetimeValidator = (notBefore, expires, securityToken, validationParameters) =>
        {
            if (expires != null)
                return expires.Value > DateTime.UtcNow;

            return false;
        },
    };
});
builder.Services.AddAuthorization();
...
...
...

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
else
{
    app.UseGlobalExceptionHandler();
    app.UseHttpsRedirection();
}
app.UseRouting();
app.UseCors("defaultCorsPolicy");

app.UseAuthentication();//Вызвал
app.UseAuthorization();//Его тоже

app.MapHealthChecks("/health");
app.MapControllers();

app.Run();


Нужные логи:
Logs

trce: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[53]
Action Filter: After executing OnActionExecuted on filter Microsoft.AspNetCore.Mvc.ModelBinding.UnsupportedContentTypeFilter.
trce: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[52]
Result Filter: Before executing OnResultExecuting on filter Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter.
trce: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[53]
Result Filter: After executing OnResultExecuting on filter Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter.
trce: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[5]
Before executing action result Microsoft.AspNetCore.Mvc.ForbidResult.
info: Microsoft.AspNetCore.Mvc.ForbidResult[1]
Executing ForbidResult with authentication schemes (A company with such a number, website, or phone number exists.).
trce: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[6]
After executing action result Microsoft.AspNetCore.Mvc.ForbidResult.
trce: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[52]
Result Filter: Before executing OnResultExecuted on filter Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter.
trce: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[53]
Result Filter: After executing OnResultExecuted on filter Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter.
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[105]
Executed action DeliveryCompanyController.Create (serverApp) in 25.6327ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'DeliveryCompanyController.Create (serverApp)'
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: No authentication handler is registered for the scheme 'A company with such a number, website, or phone number exists.'. The registered schemes are: Bearer. Did you forget to call AddAuthentication().Add[SomeAuthHandler]("A company with such a number, website, or phone number exists.",...)?
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.g__Logged|22_0(ResourceInvoker invoker, IActionResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.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.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

JwtOptions просто конфигурация для аутентификации, с ним все в норме, дело не в нем.
Пробовал еще юзаьт другую перегрузку метода, типо такую AddAuthentication(JwtBearerDefaults.AuthenticationScheme), нечего не изменилось(не удивительно).
В чем может быть проблема? Я вроде все правильно написал, схема аут указана ведь.
  • Вопрос задан
  • 33 просмотра
Решения вопроса 1
@mvv-rus
Настоящий админ AD и ненастоящий программист
Вы неправильно используете метод ControllerBase.Forbid. Передаваемая в него строка (она, как понимаю, преобразуется в массив строк из одного элемента) - это не сообщение об ошибке, а название использованного метода аутентификации.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы