Указание схемы аутентификации для одного маршрута, который обрабатывается промежуточным программным обеспечением
У меня есть новый сайт MVC ASP.Net Core 3, на который я добавил GraphQL с помощью HotChocolate. У меня есть пользователи, входящие в систему на стороне MVC, используя аутентификацию на основе файлов cookie с Auth0:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect("Auth0", options =>
{
...
});
Но для запросов GraphQL мне нужна авторизация JWT, для которой я бы использовал:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(config =>
{
...
});
Они оба работают независимо друг от друга. Cookie auth позволяет использовать контроллер; JWT auth позволяет использовать GQL. Но я не могу понять, как получить аутентификацию cookie для контроллеров и JWT для/graphql
маршрут.
Небольшой контекст: HotChocolate использует специальное промежуточное ПО для обработки запросов, поступающих в /graphql
маршрут. Его нет на контроллере, поэтому я не могу просто указать схему сAuthorize
атрибут, поскольку нет контроллера, на который можно было бы его надеть.
Похожие вопросы
- Комбинирование аутентификации с помощью файлов cookie и токенов в ASP.NET Core - ответ здесь ("использовать структуру") расплывчатый и бесполезный.
- Настройка различных схем авторизации / аутентификации - это.Net Core 1.1, а не 3.1. API немного изменились. Пытался адаптировать его, но возникли ошибки времени выполнения:
DefaultSignInScheme
требуется.
(Было несколько других, в основном ориентированных на объединение REST и MVC, но они оба относятся к контроллерам, поэтому сценарий немного отличается.)
4 ответа
У меня была такая же проблема, поэтому я решил опубликовать свое решение на случай, если у других может быть такая же проблема.
Hot Chocolate использует схему аутентификации по умолчанию, поэтому в Startup я объявляю JWT по умолчанию:
services.AddAuthentication(options =>
{
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
И везде, где мне нужна проверка подлинности файлов cookie, я просто добавляю:
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
У меня была похожая проблема, и я хотел поделиться своим решением. В моем случае я хотел, чтобы к моему API HotChocolate были применены обе схемы аутентификации. Я смог сделать это для обычных конечных точек контроллера, добавив следующие атрибуты:
[Authorize(AuthenticationSchemes = "Bearer" + "," + "OpenIdConnect")]
Для того, чтобы обе схемы были применены к моей конечной точке HotChocolate graphql, я проделал этот трюк в моем Startup
endpoints.MapGraphQL().RequireAuthorization()
.Add((endpointBuilder) =>
{
var authAttribute = endpointBuilder.Metadata.SingleOrDefault(x =>
x is Microsoft.AspNetCore.Authorization.AuthorizeAttribute);
if (authAttribute != null)
((Microsoft.AspNetCore.Authorization.AuthorizeAttribute) authAttribute)
.AuthenticationSchemes = "Bearer" + "," +
"OpenIdConnect";
});
Вдохновленный ответом ИгнасиоМира выше, я думаю, что наконец нашел то, что кажется достаточно элегантным способом сделать это.
Предполагая, что вы хотите использовать аутентификацию Cookie для большей части вашего сайта, но какую-то другую схему (например, токены носителя JWT) для конечной точки Hot Chocolate, вы можете определить свои схемы аутентификации с аутентификацией Cookie по умолчанию, как обычно:
services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie()
.AddJwtBearer(...);
Затем добавьте обаик конечной точке GraphQL:
app.MapGraphQL()
.RequireAuthorization(new AuthorizeAttribute
{
AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme
})
.AllowAnonymous(); // Adds AllowAnonymousAttribute to the endpoint metadata
Это переопределяет схему проверки подлинности по умолчанию для конечной точки GraphQL без принудительной проверки авторизации ASP.NET.
Другими словами,
AllowAnonymousAttribute
гарантирует, что проверки авторизации оставлены собственному промежуточному программному обеспечению авторизации HotChocolate, что особенно важно, если вы хотите, чтобы проверки применялись только к полям, отмеченным HotChocolateAuthorizeAttribute
.
Я не мог понять, как это сделать. В итоге я просто разделил его на два проекта. Один предоставляет GraphQL API, а другой предоставляет веб-сайт. При этом у каждого может быть своя собственная схема авторизации.