Итак, у меня есть 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";
}
Итак, что я хочу: проверить утверждения на уровне поля (для запроса или мутации) для данного утверждения с одной или несколькими ролями в нем.