配置 Kestrel GraphQL 来验证用户身份

问题描述 投票:0回答:1

我正在创建和配置 GraphQL 服务器和 Playground。

端点

/graphql
已经需要身份验证,但
/playground
抱怨它无法访问架构(访问被拒绝)。打开 Playground 后,GraphQL 显示
"error": "Response not successful: Received status code 401"
(未授权)。

事实上,如果我尝试直接访问

/graphql
,它也会导致我访问被拒绝。似乎不需要浏览器对用户进行身份验证。

我想配置

/playground
来验证用户身份,并使用令牌来调用
/graphql

这是 Web 应用程序构建:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHealthChecks();

Settings.AppSettings = builder.Configuration;

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddMicrosoftIdentityWebApi(builder.Configuration.GetRequiredSection("AzureAd"));

builder.Services.AddSingleton<AnyScalarGraphType>();
builder.Services.AddSingleton<ServiceGraphType>();

builder.Services.AddTransient<Query>();
builder.Services.AddTransient<Mutation>();

builder.Services.AddTransient<ISchema>(s => DocumentSchema.CreateSchema());

builder.Services.AddGraphQL(b => b
  .AddErrorInfoProvider(opt => opt.ExposeExceptionDetails = true)
  .AddUserContextBuilder(new Func<HttpContext, Dictionary<string, object?>>(httpContext => new RuntimeContext(httpContext)))
  .AddSystemTextJson()
);

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
      options.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter());
    });

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

app.MapHealthChecks("/health");

app.UseGraphQL("/graphql", config =>
{
  config.AuthorizationRequired = true;
});

if (app.Environment.IsDevelopment())
{
  app.UseDeveloperExceptionPage();
  app.UseGraphQLPlayground(
    "/playground",
    new GraphQL.Server.Ui.Playground.PlaygroundOptions
    {
      GraphQLEndPoint = "/graphql",
      RequestCredentials = GraphQL.Server.Ui.Playground.RequestCredentials.Include
    }
  );
}

await app.RunAsync();

这是appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://+:4002"
      }
    }
  }
}
asp.net-core .net-core graphql kestrel-http-server
1个回答
0
投票

端点 /graphql 已经需要身份验证,但是 /playground 抱怨它无法访问架构(访问被拒绝)。 打开 Playground 后,GraphQL 显示“error”:“Response 不成功:收到状态代码 401”(未授权)。

嗯,根据您的场景和描述,问题在于 Playground 如何与您的 GraphQL 端点交互。默认情况下,Playground 本身不处理身份验证,即使您的 /graphql 端点需要授权。

在调查您的共享代码时,我注意到,在您的代码中,您已将 Playground 选项的

RequestCredentials
设置为
Include
。这指示 Playground 在请求中包含任何现有的浏览器凭据。

但是,要实现此目的,您的应用程序需要有一种机制来在访问 Playground 之前设置这些凭据。这通常涉及实现登录流程,其中用户获取访问令牌并将其存储在浏览器中。

因此,成功登录后,生成访问令牌(使用 JWT 或类似的)并将其安全地存储在浏览器中,然后您就可以使用它。

您可以尝试以下修改:

app.UseWhen(context => context.Request.Path.StartsWithSegments("/playground"), appBuilder =>
    {
        appBuilder.UseAuthentication();
    });

    app.UseGraphQLPlayground(
        "/playground",
        new GraphQL.Server.Ui.Playground.PlaygroundOptions
        {
            GraphQLEndPoint = "/graphql",
            RequestCredentials = GraphQL.Server.Ui.Playground.RequestCredentials.Include
        }
    );
© www.soinside.com 2019 - 2024. All rights reserved.