GraqhQL проблема с аутентификацией на полях с JWT - PullRequest
0 голосов
/ 20 декабря 2018

Итак, у меня есть GraphQl в качестве бэкэнда и React / Apollo в качестве Frontend.Я уже реализовал мою аутентификацию токена JWT, которая прекрасно работает.

В дополнение к этому у меня есть промежуточное программное обеспечение, в котором указан HttpContext и пользователь правильно загружен со всеми утверждениями:

namespace xxx.Web.GQL.Middleware
{
public class GraphQLMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IDocumentWriter _writer;
    private readonly IDocumentExecuter _executor;
    private readonly ISchema _schema;

    public GraphQLMiddleware(RequestDelegate next, IDocumentWriter writer, IDocumentExecuter executor, ISchema schema)
    {
        _next = next;
        _writer = writer;
        _executor = executor;
        _schema = schema;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        if (httpContext.Request.Path.StartsWithSegments("/graphql") && string.Equals(httpContext.Request.Method, "POST", StringComparison.OrdinalIgnoreCase))
        {
            string body;
            using (var streamReader = new StreamReader(httpContext.Request.Body))
            {
                body = await streamReader.ReadToEndAsync();

                var request = JsonConvert.DeserializeObject<GraphQLQuery>(body);

                var result = await _executor.ExecuteAsync(doc =>
                {
                    doc.Schema = _schema;
                    doc.Query = request.Query;
                    doc.Inputs = request.Variables.ToInputs();
                    doc.ExposeExceptions = true;
                    doc.UserContext = httpContext.User;
                }).ConfigureAwait(false);

                var json = _writer.Write(result);
                await httpContext.Response.WriteAsync(json);
            }
        }
        else
        {
            await _next(httpContext);
        }
    }
}
}

Пока здесь все работает отлично.

К сожалению, я борюсь с дальнейшим.Я добавил GraphQL.Authorization Nuget, но всей данной информации недостаточно для того, чтобы я мог создать с ним какой-то рабочий код.

Что я мог бы сделать, это, конечно, получить доступ к userContext в преобразователе запроса и проверить его "от руки ", но я стараюсь избегать этого;)

Field<StringGraphType>(
          name: "hallo",
          resolve: c =>
          {
              var userPrinc = (ClaimsPrincipal)c.UserContext;
              var allowed = userPrinc.Claims.Any(x => x.Type == "Role" && x.Value == "Admin" || x.Value == "Mod");
              if (!allowed)
              {
                  throw new Exception("TODO: Make this a 401 FORBIDDEN");
              }
              return "World";
          }

Итак, что я хочу: проверить утверждения на уровне поля (для запроса или мутации) для данного утверждения с одной или несколькими ролями в нем.

1 Ответ

0 голосов
/ 07 января 2019

Сначала нужно определить политику.Сделайте это методом ConfigureServices.Например:

services.AddGraphQLAuth(_ =>
{
    _.AddPolicy("name-of-policy", p => p.RequireClaim("role", "admin"));
});

И убедитесь, что добавляете пользовательский контекст с помощью метода AddUserContextBuilder, например:

services.AddGraphQL(options =>
{
    options.ExposeExceptions = true;
}).AddUserContextBuilder(context => new GraphQLUserContext { User = context.User });

Наконец, вам нужно использовать метод расширения AuthorizeWithэто часть GraphQL.Authorization на поле.Например:

Field<StringGraphType>( /* snip */ )
    .AuthorizeWith("name-of-policy");

Взгляните на пример здесь: https://github.com/graphql-dotnet/authorization/tree/master/src/Harness

...