Это можно сделать с помощью авторизации на основе политик.
Идея, по сути, заключается в том, что у вас есть требование, которое должно быть выполнено (действительный сертификат), обработчик для требования (как проверить сертификат) и политика, которая обеспечивает соблюдение этого требования и применяется во время авторизации.
Если ваш код достаточно прост, вы можете просто указать Func<AuthorizationHandlerContext, bool>
для политики, которая применяется для оценки. Вот как настроить политику (в Startup.cs, ConfigureServices()
):
services.AddAuthorization(options =>
{
options.AddPolicy("ValidateCertificate", policy =>
policy.RequireAssertion(context =>
{
var filterContext = (AuthorizationFilterContext)context.Resource;
var Response = filterContext.HttpContext.Response;
var message = Encoding.UTF8.GetBytes("Invalid certificate");
Response.OnStarting(async () =>
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
await Response.Body.WriteAsync(message, 0, message.Length);
});
return false;
}));
});
Это будет делать то, что вы хотите.
Теперь, если вы хотите пойти по более структурированному маршруту, вы можете реализовать каждый фрагмент:
Сначала создайте ваше требование (больше похоже на маркер для справки):
public class ValidCertificateRequirement : IAuthorizationRequirement
{
}
Затем настройте политику, которую нужно применить (Startup.cs, ConfigureServices()
):
services.AddAuthorization(options =>
{
options.AddPolicy("ValidateCertificate", policy =>
{
policy.Requirements.Add(new ValidCertificateRequirement());
});
});
Теперь вам нужно создать обработчик требований:
public class ValidCertificateHandler : AuthorizationHandler<ValidCertificateRequirement>
{
public ValidCertificateHandler()
{
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ValidCertificateRequirement requirement)
{
var filterContext = (AuthorizationFilterContext)context.Resource;
var Response = filterContext.HttpContext.Response;
var message = Encoding.UTF8.GetBytes("Invalid certificate");
Response.OnStarting(async () =>
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
await Response.Body.WriteAsync(message, 0, message.Length);
});
context.Fail();
return Task.CompletedTask;
}
}
Обработчик должен быть зарегистрирован при запуске (в ConfigureServices()
):
//Register handler
services.AddSingleton<IAuthorizationHandler, ValidCertificateHandler>();
Наконец, для любого из подходов (утверждение или реализация) примените атрибут Authorize
к своим действиям, указывая политику для применения:
[Authorize(Policy = "ValidateCertificate")]
public HttpResponseMessage TestAuth()
{
return new HttpResponseMessage(HttpStatusCode.OK)
{
ReasonPhrase = "In Test method without any authorization."
};
}
Подробнее об этом можно прочитать здесь:
Авторизация на основе политик в ASP.NET Core