2

我有一个新的 ASP.Net Core 3 MVC 站点,已将 GraphQL 添加到HotChocolate中。我有用户使用基于 cookie 的身份验证和 Auth0 登录到 MVC 端:

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 身份验证和/graphql路由的 JWT。

一点上下文:HotChocolate 使用自定义中间件来处理进入/graphql路由的请求。它不在控制器上,所以我不能只用Authorize属性指定方案,因为没有控制器可以把它放在上面。

类似问题

(还有一些其他的,主要专注于结合 REST 和 MVC,但它们都用于控制器,所以场景有点不同。)

4

4 回答 4

2

我有同样的问题,所以我想我发布我的解决方案以防其他人可能有同样的问题。

Hot Chocolate 使用默认身份验证方案,因此在启动时我将 JWT 声明为默认值:

    services.AddAuthentication(options =>
    {
        options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

    })

在任何需要 Cookie 身份验证的地方,我只需添加:

[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
于 2020-12-30T23:27:04.477 回答
2

我有一个非常相似的问题,我想分享我的解决方案。就我而言,我希望将两种身份验证模式都应用于我的 HotChocolate api。通过添加以下属性,我能够为普通控制器端点执行此操作:

[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";
            });
于 2021-09-13T20:14:23.217 回答
0

我不知道该怎么做。我最终只是把它分成两个项目。一个提供 GraphQL API,另一个提供网站。这样做,每个人都可以有自己的身份验证方案。

于 2020-04-15T23:13:38.067 回答
0

从上面 IgnacioMir 的回答中得到灵感,我想我终于找到了一种相当优雅的方法。

假设您想对大部分站点使用 Cookie 身份验证,但对 Hot Chocolate 端点使用其他方案(例如 JWT 不记名令牌),那么您可以将身份验证方案定义为默认的 Cookie 身份验证:

services
    .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie()
    .AddJwtBearer(...);

然后将 anAuthorizeAttribute和 an添加AllowAnonymousAttribute到 GraphQL 端点:

app.MapGraphQL()
    .RequireAuthorization(new AuthorizeAttribute
    {
        AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme
    })
    .AllowAnonymous(); // Adds AllowAnonymousAttribute to the endpoint metadata

这会覆盖 GraphQL 端点的默认身份验证方案,而不需要 ASP.NET 强制执行任何授权检查。

换句话说,AllowAnonymousAttribute确保授权检查留给 HotChocolate 自己的授权中间件,如果您只想将检查应用于标记有 HotChocolate 的字段,这一点尤其重要AuthorizeAttribute

于 2022-02-05T16:50:06.297 回答