所以我将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);
}
}
}
}
所以我想要的是: 在给定声明中具有一个或多个角色的字段级别(用于查询或突变)中检查声明。
答案 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