Аутентификация GraphQL с ядром Asp.net с использованием JWT

Я использую пакет GraphQL для .NET для graphql. Но я не мог понять, как я могу аутентифицироваться с помощью JWT в запросе или мутации graphql.

Я прочитал руководство по авторизации, но не смог.

Мне нужна помощь с GraphQL для аутентификации .NET.

Любая помощь будет оценена по достоинству.

Спасибо

Не уверен, что понимаю их отношение. С JWT вы аутентифицируете пользователя в своем приложении. К тому времени, когда он выполняет действие контроллера, пользователь заполняется утверждениями и может быть использован с примером, который вы связали?

Tseng 31.05.2018 18:49

Но мы должны авторизовать запрос graphql, используя полезную нагрузку JWT?

tcetin 31.05.2018 19:01

На первый взгляд (не вдавались в подробности) связанный пример использует только IPrincipal / ClaimsPrincipal соответственно. Все, что вам нужно сделать, это проверить, есть ли у пользователя определенные претензии (в этом примере). Претензии, которые уже были заполнены ранее во время запроса. Прочтите, вы отправляете заявку в свой API, который заполняет Свойство пользователя утверждениями и всей другой информацией. На этом этапе вам больше не нужно беспокоиться, если пользователь аутентифицирован через jwt, cookie или что-то еще.

Tseng 31.05.2018 19:06

Хорошо, я понял. Спасибо. Но в том же руководстве рассказывается о реализации. Но в нем много ошибок. Может мне это нужно? Вот реализация: github.com/graphql-dotnet/authorization

tcetin 31.05.2018 20:05
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
4
5 427
2

Ответы 2

Руководство посвящено авторизации. Шаг, который вы ищете, - это аутентификация, и поскольку graphql может быть реализован с использованием контроллера API ASP.Net, вы можете реализовать аутентификацию JWT, как и с любым контроллером.

Вот пример контроллера grapql, использующего атрибут авторизации. Однако вы можете реализовать это с помощью фильтра или, если вам нужен полный контроль, настраиваемого промежуточного программного обеспечения.

[Route("api/[controller]")]
[ApiController]
[Authorize]
public class GraphQLController : ControllerBase
{
    private readonly IDocumentExecuter executer;
    private readonly ISchema schema;

    public GraphQLController(IDocumentExecuter executer, ISchema schema)
    {
        this.executer = executer;
        this.schema = schema;
    }

    [HttpPost]
    public async Task<ActionResult<object>> PostAsync([FromBody]GraphQLQuery query)
    {
        var inputs = query.Variables.ToInputs();
        var queryToExecute = query.Query;

        var result = await executer.ExecuteAsync(o => {
            o.Schema = schema;
            o.Query = queryToExecute;
            o.OperationName = query.OperationName;
            o.Inputs = inputs;

            o.ComplexityConfiguration = new GraphQL.Validation.Complexity.ComplexityConfiguration { MaxDepth = 15};
            o.FieldMiddleware.Use<InstrumentFieldsMiddleware>();
        }).ConfigureAwait(false);

        return this.Ok(result);
    }
}

public class GraphQLQuery
{
    public string OperationName { get; set; }
    public string Query { get; set; }
    public Newtonsoft.Json.Linq.JObject Variables { get; set; }
}

В Startup.cs я настроил аутентификацию токена-носителя JWT.

Надеюсь это поможет.

Я сам тоже боролся два дня. Я сейчас использую https://github.com/graphql-dotnet/authorization с настройкой из этого комментария (от меня): https://github.com/graphql-dotnet/authorization/issues/63#issuecomment-553877731

Вкратце, вы должны правильно настроить UserContext для AuthorizationValidationRule, вот так:

public class Startup
{
    public virtual void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddGraphQLAuth(_ =>
        {
            _.AddPolicy("AdminPolicy", p => p.RequireClaim("Role", "Admin"));
        });
        services.AddScoped<IDependencyResolver>(x => new FuncDependencyResolver(x.GetRequiredService));
        services.AddScoped<MySchema>();
        services
            .AddGraphQL(options => { options.ExposeExceptions = true; })
            .AddGraphTypes(ServiceLifetime.Scoped);
        ...
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
    {
        ...
        app.UseMiddleware<MapRolesForGraphQLMiddleware>(); // optional, only when you don't have a "Role" claim in your token
        app.UseGraphQL<MySchema>();
        ...
    }
}

public static class GraphQLAuthExtensions
{
    public static void AddGraphQLAuth(this IServiceCollection services, Action<AuthorizationSettings> configure)
    {
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddSingleton<IAuthorizationEvaluator, AuthorizationEvaluator>();
        services.AddTransient<IValidationRule, AuthorizationValidationRule>();

        services.AddTransient<IUserContextBuilder>(s => new UserContextBuilder<GraphQLUserContext>(context =>
        {
            var userContext = new GraphQLUserContext
            {
                User = context.User
            };

            return Task.FromResult(userContext);
        }));

        services.AddSingleton(s =>
        {
            var authSettings = new AuthorizationSettings();
            configure(authSettings);
            return authSettings;
        });
    }
}

public class GraphQLUserContext : IProvideClaimsPrincipal
{
    public ClaimsPrincipal User { get; set; }
}

public class MapRolesForGraphQLMiddleware
{
    private readonly RequestDelegate _next;

    public MapRolesForGraphQLMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        // custom mapping code to end up with a "Role" claim
        var metadata = context.User.Claims.SingleOrDefault(x => x.Type.Equals("metadata"));

        if (metadata != null)
        {
            var roleContainer = JsonConvert.DeserializeObject<RoleContainer>(metadata.Value);
            (context.User.Identity as ClaimsIdentity).AddClaim(new Claim("Role", string.Join(", ", roleContainer.Roles)));
        }

        await _next(context);
    }
}

public class RoleContainer
{
    public String[] Roles { get; set; }
}

Другие вопросы по теме