使用JWT对字段进行身份验证的GraqhQL问题

时间:2018-12-20 17:14:17

标签: c# graphql graphql-dotnet

所以我将graphql作为后端,并将React / Apollo作为前端。 我已经实现了JWT令牌身份验证,效果很好。

此外,我还有我的中间件,其中提供了HttpContext,并且已正确加载了所有声明的用户信息:

ExecuteQuery<int>

直到这里它都能正常工作。

可悲的是,我在进一步努力。我添加了GraphQL.Authorization Nuget,但是所有给定的信息不足以使我可以用它构建一些工作代码。

我能做的当然是在查询的解析器中访问userContext并“手动”检查它,但我尝试避免它;)

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);
        }
    }
}
}

所以我想要的是: 在给定声明中具有一个或多个角色的字段级别(用于查询或突变)中检查声明。

1 个答案:

答案 0 :(得分:2)

第一个需要定义策略。使用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