Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement authorization using GraphQL.NET at Resolver function level?

I am looking for sample code and examples regarding how to implement authorization at resolver function level using GraphQL.NET and ASP.NET CORE 2.

Basically I am trying to prevent the execution of query if the request is not authorized.

Can anyone help me to get some good tutorials or code samples as reference for the implementation.

like image 518
santosh kumar patro Avatar asked Nov 29 '18 11:11

santosh kumar patro


People also ask

How does GraphQL authentication work?

Authenticating GraphQL is quite simple. We make use of queries and mutations. For a user to have access he has to register first, that's why we have register pages on almost all websites. The registration hits a particular endpoint, for example, it is usually like this https://URL_HERE/register API in a REST endpoint.

What does a GraphQL client usually do before caching the results of a query?

Generally, when caching data, the intuition is to put information that's fetched remotely into a local store from where it can be retrieved later on. With GraphQL, the naive approach would be to simply put the results of GraphQL queries into the store and simply return them whenever the same query is sent.


1 Answers

For graphql-dotnet/authorization, the page for AspNetCore has not been released, refer Add GraphQL.Server.Authorization.AspNetCore NuGet package #171.

You could implement Authorization.AspNetCore for your own use.

After implement Authorization.AspNetCore, you could configure the Authorize like:

  • Startup.cs

        public class Startup
    {
        public Startup(IConfiguration configuration, IHostingEnvironment hostingEnvironment)
        {
            Configuration = configuration;
            Environment = hostingEnvironment;
        }
    
        public IConfiguration Configuration { get; }
        public IHostingEnvironment Environment { get; }
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
            services.AddAuthentication(option =>
            {
                option.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                option.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            }).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
            services.AddGraphQL(options =>
            {
                options.EnableMetrics = true;
                options.ExposeExceptions = Environment.IsDevelopment();
    
                //options.
            })
            .AddGraphQLAuthorization(options =>
            {
                options.AddPolicy("Authorized", p => p.RequireAuthenticatedUser());
                //var policy = new AuthorizationPolicyBuilder()
                //                    .
                //options.AddPolicy("Authorized", p => p.RequireClaim(ClaimTypes.Name, "Tom"));
            });
            //.AddUserContextBuilder(context => new GraphQLUserContext { User = context.User });
    
            services.AddSingleton<MessageSchema>();
            services.AddSingleton<MessageQuery>();
    
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
    
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseAuthentication();
            app.UseGraphQL<MessageSchema>("/graphql");
            app.UseGraphQLPlayground(new GraphQLPlaygroundOptions()
            {
                Path = "/ui/playground"
            });
            app.UseGraphiQLServer(new GraphiQLOptions
            {
                GraphiQLPath = "/ui/graphiql",
                GraphQLEndPoint = "/graphql"
            });
    
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
    
  • Schema

    public class MessageQuery : ObjectGraphType<Message>
    {
        public MessageQuery()
        {
            Field(o => o.Content).Resolve(o => "This is Content").AuthorizeWith("Authorized");
            Field(o => o.SentAt);
            Field(o => o.Sub).Resolve(o => "This is Sub");
        }
    }
    

For complete demo, refer GraphQLNet.

like image 155
Edward Avatar answered Oct 20 '22 00:10

Edward