Мне не удается заставить мой настраиваемый фильтр IAuthenticationFilter работать в WebAPI 2. Net стандарт 4.8.
Я создаю приложение с использованием шаблона WebAPI - БЕЗ безопасности. Я добавляю контроллер с приведенным ниже кодом, который также содержит абсолютную базовую c реализацию пользовательского AuthenticationFilter и пользовательского AuthorizeAttribute.
Я могу без проблем попасть в конечную точку «открытого» контроллера.
В другой конечной точке я пытаюсь надеть ТОЛЬКО AuthorizeAttribute, и он работает - запускается код атрибута Authorize "IsAuthorized", а затем действие контроллера. Если я затем заменю этот атрибут настраиваемым фильтром аутентификации - ИЛИ если добавлю к нему фильтр аутентификации, то мой код AuthenticateAsyn c - и установит IPrincipal контекста, но затем, вместо того, чтобы что-то еще работает, следующий вызов идет к ChallengeAsyn c и больше ничего не запускается.
Что я делаю не так?
Я получил код прямо из множества скопированных и вставленных постов в блоге и документов MS, объясняющих AuthenticationFilter .... или так я думал. https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-filters
Обратите внимание, что я проверил этот вопрос: Разница между AuthorizeAttribute и IAuthenticationFilter
... но ответ не относится к IAuthenticationFilter ...
Код для тестового контроллера следующий:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Net;
using System.Web.Http.Filters;
using System.Security.Claims;
using System.Net.Http;
using System.Web.Http.Controllers;
namespace TestApp.Api
{
// this is not working currently due to the fact that we have to do the wonky security for aspx pages
public class TestFilterAttribute : Attribute, IAuthenticationFilter
{
public class BasicActionResult : IHttpActionResult
{
private HttpResponseMessage message;
public BasicActionResult(HttpResponseMessage message)
{
this.message = message;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) => Task.FromResult(message);
}
public bool AllowMultiple => false;
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
context.Result = new BasicActionResult(context.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid Authorization"));
return Task.FromResult(0);
}
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, "testUser"));
claims.Add(new Claim("email", "testUser@test.local"));
var id = new ClaimsIdentity(claims, "Token");
context.Principal = new ClaimsPrincipal(new ClaimsIdentity[] { id });
return Task.FromResult(0);
}
}
public class TestAuthorizeAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext context)
{
var principal = context.Request.GetRequestContext().Principal as ClaimsPrincipal;
if (principal == null) return false;
return true;
}
}
[RoutePrefix("api/test")]
public class TestController : ApiController
{
[HttpGet]
[Route("open")]
public string TestOpen()
{
return "TestOpen Works";
}
[HttpGet]
[Route("secure")]
[TestAuthorize]
public string TestSecured()
{
return "TestSecured Works";
}
}
}