代码之家  ›  专栏  ›  技术社区  ›  PassionateDeveloper

JWT域上auth的GraqhQL问题

  •  1
  • PassionateDeveloper  · 技术社区  · 6 年前

    所以我将graphql作为后端,React/Apollo作为前端。

    除此之外,我还有我的中间件,其中给出了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 numget,但是所有给定的信息都不足以用它构建一些工作代码。

    我能做的当然是访问查询解析器中的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 回复  |  直到 6 年前
        1
  •  4
  •   ΩmegaMan    6 年前

    首先需要定义策略。在里面做这个 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

    推荐文章