graphql-dotnet / authorization

A toolset for authorizing access to graph types for GraphQL .NET.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Code in ReadMe Doesn't Compile

FunkMonkey33 opened this issue · comments

type not found: GraphQLMiddleware. Also not in the Harness anywhere.

GraphQLSettings defines BuildUserContext with a Task, but the readme code tries to use it as a Task. I fixed by redefining BuildUserContext to use a Task.

Code in Harness looks nothing like Readme code.

Great library. Would love to know how to use it.

Github took out my angle brackets. second paragraph should read: GraphQLSettings defines a BuildUserContext with a Task of type object, but the readme code tries to use it as a Task of type GraphQLUserContext. I fixed by redefining BuildUserContext to use a Task of type GraphQLUserContext.

Same here. I'm struggling with authorization as well. I'm a real noob and I need a very simple file structure to start

Same issue here. Can't find that 'GraphQLMiddleware' bit anywhere, unless it is supposed to be a custom class?

Over a year later... docs still aren't fixed, and code seems to have drifted even further from the example. It's hard to tell if this library is even supported, or if I'm wasting my time trying to implement it.

I also worry that I do not have the time (and sometimes the energy) to support the project as I would like it to.

@zaneclaes The readme will never contain all of the code necessary for a fully working server, there are too many moving pieces with a GraphQL server. The code in the readme is to get the basic concepts across.

Can you point out what you feel is a problem with the readme? What do you feel like should be "fixed"? I have reviewed it and there is only a single item that is missing from the 3.0 refactor.

This is an advanced feature to a server and expects some prior knowledge.

Perhaps one option is to not have ASP.NET Core specifics in the readme, just make it a console app. That would shorten the example and perhaps remove the confusion around actually wiring things up to a server.

Added a "basic sample" project, and updated the readme with a Console app which you can just copy/paste to see it work.

Sample.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\GraphQL.Authorization\GraphQL.Authorization.csproj" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="GraphQL.SystemTextJson" Version="3.0.0.2026" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.9" />
  </ItemGroup>

</Project>

Program.cs:

namespace BasicSample
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Claims;
    using System.Threading.Tasks;
    using Microsoft.Extensions.DependencyInjection;
    using GraphQL;
    using GraphQL.Types;
    using GraphQL.Validation;
    using GraphQL.SystemTextJson;

    using GraphQL.Authorization;

    class Program
    {
        static async Task Main(string[] args)
        {
            var services = new ServiceCollection();
            services.AddSingleton<IAuthorizationEvaluator, AuthorizationEvaluator>();
            services.AddTransient<IValidationRule, AuthorizationValidationRule>();
            services.AddTransient(s =>
            {
                var authSettings = new AuthorizationSettings();
                authSettings.AddPolicy("AdminPolicy", p => p.RequireClaim("role", "Admin"));
                return authSettings;
            });

            var serviceProvider = services.BuildServiceProvider();

            var definitions = @"
                type User {
                    id: ID
                    name: String
                }

                type Query {
                    viewer: User
                    users: [User]
                }
            ";
            var schema = Schema.For(
                definitions,
                _ =>
                {
                    _.Types.Include<Query>();
                });

            // remove claims to see the failure
            var authorizedUser = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("role", "Admin") }));

            var json = await schema.ExecuteAsync(_ =>
            {
                _.Query = "{ viewer { id name } }";
                _.ValidationRules = serviceProvider
                    .GetServices<IValidationRule>()
                    .Concat(DocumentValidator.CoreRules);
                _.RequestServices = serviceProvider;
                _.UserContext = new GraphQLUserContext { User = authorizedUser };
            });

            Console.WriteLine(json);
        }
    }

    public class GraphQLUserContext : Dictionary<string, object>, IProvideClaimsPrincipal
    {
        public ClaimsPrincipal User { get; set; }
    }

    public class Query
    {
        [GraphQLAuthorize(Policy = "AdminPolicy")]
        public User Viewer()
        {
            return new User { Id = Guid.NewGuid().ToString(), Name = "Quinn" };
        }

        public List<User> Users()
        {
            return new List<User> { new User { Id = Guid.NewGuid().ToString(), Name = "Quinn" } };
        }
    }

    public class User
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }
}