Course contentsShow
← C#
Lesson 1228 of 1,90811. Identity, Security, and ClaimsFree lesson

Authorization and Entity Framework Security

Filter query results based on user identity automatically using global query filters.

In this lesson, you will learn how to secure your data at the database level by using Entity Framework Core (EF Core) Global Query Filters to automatically restrict data access based on the currently authenticated user.

The Problem: Manual Filtering

Up until now, we have handled authorization by checking claims in controllers or services. However, if you have hundreds of queries across your application, it is easy to forget a .Where(x => x.OwnerId == userId) clause, potentially exposing data to unauthorized users. Global query filters allow us to enforce this rule globally at the persistence layer.

Implementing Global Query Filters

To implement this, you need access to the user's identity within your DbContext. Since the DbContext is scoped, you can inject IHttpContextAccessor to retrieve the current user's claims.

Here is how you define a global filter in your DbContext:

public class ApplicationDbContext : DbContext
{
    private readonly string _currentUserId;

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor) 
        : base(options)
    {
        _currentUserId = httpContextAccessor.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Apply a global filter to the 'Documents' entity
        modelBuilder.Entity<Document>().HasQueryFilter(d => d.OwnerId == _currentUserId);
    }
}

How it Works

Once configured, any LINQ query you execute against the Documents DbSet—such as context.Documents.ToList()—will have the d.OwnerId == _currentUserId predicate automatically appended by EF Core. This happens before the SQL is generated, ensuring that the database only returns rows that the current user is authorized to see.

Important Considerations

  1. Bypassing Filters: Occasionally, you may need to access restricted data (e.g., for an admin dashboard). You can use .IgnoreQueryFilters() to temporarily disable this behavior for a specific query.
  2. Performance: Ensure that the property you are filtering by (e.g., OwnerId) is indexed in your database, as this filter will now be appended to every single query targeting that table.

Key Takeaway: Global query filters shift authorization from a manual "developer responsibility" to an automated "database contract," ensuring that unauthorized data is inaccessible by default.