Skip to main content

Authorization

You should secure the route where you app/client posts request to in any ASP.NET supports. Given GraphQL works with a schema you likely want to provide authorization within the schema. EntityGraphQL provides support for checking claims on a ClaimsPrincipal object.

Passing in the User

First pass in the ClaimsPrincipal to the query call

Note if you are using the AddGraphQLSchema() extension in EntityGraphQL.AspNet this is already handled for you.

// Assuming you're in a ASP.NET controller
// this.User is the current ClaimsPrincipal
var results = await schemaProvider.ExecuteRequestAsync(query, dbContext, this.HttpContext.RequestServices, this.User);

Adding Authorization on Roles or Policies

You can add authorization requirements throughout your schema even using the AuthorizeAttribute or when building/modifying your schema.

_Note: if you provide multiple [AuthorizeAttribute] attributes on a single field/mutation they are treated as AND meaning all are required. If you provide a single [AuthorizeAttribute] attribute with multiple roles/policies in a comma-separated string they are treated as OR i.e. having any of those listed will authorize access.

Mutations

Mark you mutation methods with the [Authorize(Roles = "role-name")] attribute.

Policy authorization with [Authorize(Policy = "policy-name")] is also supported when using EntityGraphQL.AspNet.

public class MovieMutations
{
[GraphQLMutation]
[Authorize(Roles = "movie-editor")]
public Movie AddActor(MyDbContext db, ActorArgs args)
{
// ...
}
}

If a ClaimsPrincipal is provided with the query call it will be required to be Authorized and have a Role of movie-editor to call this mutation.

Queries

If you are using the SchemaBuilder.FromObject<TContext>() you can use the [Authorize(Roles = "role-name")] attribute again throughout the objects.

public class MyDbContext : DbContext {
protected override void OnModelCreating(ModelBuilder builder) {
// Set up your relations
}

// require either claim
[Authorize(Roles = "property-role,admin-property-role")]
public DbSet<Property> Properties { get; set; }
public DbSet<PropertyType> PropertyTypes { get; set; }
public DbSet<Location> Locations { get; set; }
}

public class Property {
public uint Id { get; set; }
public string Name { get; set; }
public PropertyType Type { get; set; }
// require both claims
[Authorize(Roles = "property-admin")]
[Authorize(Roles = "super-admin")]
public Location Location { get; set; }
}

// ....

You can secure whole types with the attribute too.

[Authorize(Roles = "property-user")]
public class Property {
public uint Id { get; set; }
public string Name { get; set; }
public PropertyType Type { get; set; }
public Location Location { get; set; }
}

If a ClaimsPrincipal is provided with the ExecuteRequest call it will be required to be Authorized and have the Role property-role to query the root-level properties field and the role property-admin to query the Property field location.

Authorization can be provided in the API for add/replacing fields on the schema object.

schemaProvider.AddField("myField", (db) => db.MyEntities, "Description").RequiresAllRoles("admin");
schemaProvider.AddField("myField", (db) => db.MyEntities, "Description").RequiresAnyRole("admin", "super-admin");

schemaProvider.AddType<Property>("properties", (db) => db.Properties, "Description").RequiresAllRoles("property-user");
schemaProvider.AddType<Property>("properties", (db) => db.Properties, "Description").RequiresAnyRole("property-user", "property-admin");

Note when using AddField() and AddType() these functions will automatically search for [Authorize()] attributes on the fields and types.

Authorization without ASP.Net

You can use the GraphQLAuthorizeAttribute with role claims to provide authorization without the ASP.Net dependency.