Web API project with GraphQL / Entity Framework / SQL / .NET Identity Authorisation demonstrating row-level security of GraphQL queries based on Role.
.NET 6 Microsoft SQL Database (localdb) Entity Framework Core 6 .NET Identity Graph QL Hot Chocolate UI for Graph SQL
- Projections
- Filtering
- Sorting
- Authentication
- Authorization
- Row-level security (filtering data by role)
- Clone the repo
- Update your localdb connection string in
appsettings.json
if necessary - Migrate and seed the database with
update-database
- Run the web app
- Register a new account with any email address (no email confirmation required)
- You will be redirected to Hot Chocolate GraphQL UI
- Run the following query
query{
superheroes
{
name
height
}
}
Only "Batman" will be returned because "Level3Admin" role is required to see Superheroes above 1.8m in height).
- Open SQL Server Management Studio
- Add your user to the "Level3Admin" role in the
AspNetUserRoles
table. Seeded "Level3Admin" Role ID is:4f9c41ec-780e-4a18-8de1-4f3d5b23ef31
- Restart the application
- Clear your Cookies in Chrome Tools in order to "Log out"
- Log back in again with your user
- Run the same query
query{
superheroes
{
name
height
}
}
This time all of the Superheroes are returned because you are a "Level3Admin"
In the resolver for the query (Query.cs
), we get the user (from IHttpContextAccessor
) and look up the roles.
We can then filter the EF Linq query in the usual way:
[Authorize]
public class Query
{
[UseProjection]
[UseFiltering]
[UseSorting]
public async Task<IQueryable<Superhero>> GetSuperheroes(
[Service] ApplicationDbContext context,
[Service]UserManager<User> userManager,
[Service]IHttpContextAccessor httpContextAccessor)
{
var user = await userManager.FindByNameAsync(httpContextAccessor.HttpContext.User.Identity.Name);
var isLevel3Admin = await userManager.IsInRoleAsync(user, Roles.Level3Admin);
return context.Superheroes.Where(s =>
// Row level security filtering based on role
(s.Height > 1.8 || isLevel3Admin)
);
}
}
Tutorial on GraphQL with Entity Framework https://christian-schou.dk/how-to-implement-graphql-in-asp-net-core/
How to implement authorization using GraphQL.NET at Resolver function level? https://stackoverflow.com/questions/53537521/how-to-implement-authorization-using-graphql-net-at-resolver-function-level
GraphQL: Simple authorization and authentication with HotChocolate 11 and ASP.NET Core 3 https://medium.com/@marcinjaniak/graphql-simple-authorization-and-authentication-with-hotchocolate-11-and-asp-net-core-3-162e0a35743d
graphql-dotnet Authorization - Getting Started https://graphql-dotnet.github.io/docs/getting-started/authorization/