devdeer.Libraries.Repository.EntityFrameworkCore.Authorized 12.0.6

There is a newer version of this package available.
See the version list below for details.
dotnet add package devdeer.Libraries.Repository.EntityFrameworkCore.Authorized --version 12.0.6
                    
NuGet\Install-Package devdeer.Libraries.Repository.EntityFrameworkCore.Authorized -Version 12.0.6
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="devdeer.Libraries.Repository.EntityFrameworkCore.Authorized" Version="12.0.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="devdeer.Libraries.Repository.EntityFrameworkCore.Authorized" Version="12.0.6" />
                    
Directory.Packages.props
<PackageReference Include="devdeer.Libraries.Repository.EntityFrameworkCore.Authorized" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add devdeer.Libraries.Repository.EntityFrameworkCore.Authorized --version 12.0.6
                    
#r "nuget: devdeer.Libraries.Repository.EntityFrameworkCore.Authorized, 12.0.6"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package devdeer.Libraries.Repository.EntityFrameworkCore.Authorized@12.0.6
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=devdeer.Libraries.Repository.EntityFrameworkCore.Authorized&version=12.0.6
                    
Install as a Cake Addin
#tool nuget:?package=devdeer.Libraries.Repository.EntityFrameworkCore.Authorized&version=12.0.6
                    
Install as a Cake Tool

devdeer.Libraries.Repository.EntityFrameworkCore.Authorized

NuGet Downloads

Disclaimer

If you want to use this package you should be aware of some principles and practices we at DEVDEER use. So be aware that this is not backed by a public repository. The purpose here is to give out customers easy access to our logic. Nevertheless you are welcome to use this lib if it provides any advantages.

Summary

The purpose of this package is to simplify and standardize the process of performing HTTP context user detection and automated role management for an API using Azure AD and a backend using EF Core code first.

Using this package automatically leads to changes in the database structure. Again be aware that this is completely built around the standards of DEVDEER.

Usage

After you added a Nuget reference to your project you should first inherit your DbContext from SimpleAuthorizationContext instead of DbContext. This will add some additional logic to your context which is needed to work with the repository.

public class MyContext : SimpleAuthorizationContext
{
     public MyContext(DbContextOptions dbContextOptions,
        IOptions<EntityFrameworkAuthorizationOptions> authorizationOptions) : base(dbContextOptions, authorizationOptions)
     {
     }

}

You should now take care about your settings. In the appsettings.json there should be a new setting:

"EfCoreAuthorization": {
    "IsEnabled": true,
    "AutoCreateNewUsers": true,
    "AutoCreateRoleKey": "GUE",
    "UseCaching": true,
    "CacheTimeoutSeconds": 1800,
    "RequiredRoles": [
        {
            "Id": 1,
            "ParentId": null,
            "UniqueKey": "GUE",
            "DisplayLabel": "Guest"
        },
        {
            "Id": 2,
            "ParentId": 1,
            "UniqueKey": "USR",
            "DisplayLabel": "User"
        },
        {
            "Id": 3,
            "ParentId": 2,
            "UniqueKey": "ADM",
            "DisplayLabel": "Administrator"
        }
    ]
}

The code above shows kind of the default configuration. It enables the authorization using this package and ensures that users always will be automatically created whenever they "arrive" at the API as bearer tokens. For this it will use a role assignment with the key specicfied which in turn must be one of the unique keys you specified in the RequiredRoles section. The UseCaching option switches memory caching of users on using the CacheTimeoutSeconds as timeout.

The RequiredRoles section is used to define which roles should be available in the database. The ParentId allows you to create a hierarchy here. In the sample shown all admins will be members of users als which in turn are always implcitly members of the guest.

If you are using EF Core migrations using the IDesignTimeDbContextFactory pattern you need to ensure that this is passed to your context instance there as follows:

public MyContext CreateDbContext(string[] args)
{
    var options = new DbContextOptionsBuilder<MyContext>().UseSqlServer(
            "CONNECTIONSTRING",
            o =>
            {
                o.MigrationsHistoryTable("MigrationHistory", "SystemData");
                o.CommandTimeout(3600);
            })
        .Options;
    return new MyContext(
        options,
        Options.Create(
            new EntityFrameworkAuthorizationOptions
            {
                AutoCreateNewUsers = true,
                AutoCreateRoleKey = "GUE",
                RequiredRoles = new RoleModel[]
                {
                    new()
                    {
                        Id = 1,
                        UniqueKey = "GUE",
                        DisplayLabel = "Guest"
                    },
                    new()
                    {
                        Id = 2,
                        ParentId = 1,
                        UniqueKey = "USR",
                        DisplayLabel = "User"
                    },
                    new()
                    {
                        Id = 3,
                        ParentId = 2,
                        UniqueKey = "ADM",
                        DisplayLabel = "Administrator"
                    }
                },
                IsEnabled = true
            }));
}

Also make sure, that your MyContext override of OnModelCreating calls the parents method in any case:

/// <inheritdoc />
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    // your code here
}

Afterwards you need to create a new migration if you are using code first:

dotnet ef migrations add "AuthorizationStructure"
dotnet ef database update

Whereever you are performing application startup is the place where you now generate 3 implementations:

public class DefaultAuthorizationMiddlewareResultHandler : BaseSimpleAuthorizationMiddlewareResultHandler<MyContext>
{
    #region constructors and destructors

    /// <inheritdoc />
    public DefaultAuthorizationMiddlewareResultHandler(
        AuthOptions authorizationOptions,
        IAuthorizedUserRepository<long, User, Role, UserRole, UserModel> repository) : base(
        authorizationOptions,
        repository)
    {
    }

    #endregion
}

public class DefaultAuthorizedUserRepository : BaseSimpleAuthorizedUserRepository<MyContext>
{
    #region constructors and destructors

    /// <inheritdoc />
    public DefaultAuthorizedUserRepository(
        IServiceProvider serviceProvider,
        MyContext dbContext,
        IMapper mapper) : base(serviceProvider, dbContext, mapper)
    {
    }

    #endregion
}

public class DefaultRolesAuthorizationHandler : BaseSimpleAuthorizationHandler<MyContext>
{
    #region constructors and destructors

    /// <inheritdoc />
    public DefaultRolesAuthorizationHandler(
        IAuthorizedUserRepository<long, User, Role, UserRole, UserModel> repository) : base(repository)
    {
    }

    #endregion
}

Now you can call the DI configuration using these types:

builder.Services
    .ConfigureAuthorizationDefaults<DefaultAuthorizationMiddlewareResultHandler, DefaultRolesAuthorizationHandler,
        DefaultAuthorizedUserRepository, MyContext>();

To test this you could add a simple controller like

[ApiController]
[Authorize]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class UserController : ControllerBase
{

    public UserController(ISimpleAuthorizedUserRepository repository)
    {
        Repository = repository;
    }

    [HttpGet("Me")]
    [Authorize(Roles = "GUE")]
    public async ValueTask<ActionResult<UserModel?>> GetAsync()
    {
        var userData = await Repository.GetOrCreateUserAsync();
        return Ok(userData);
    }

    [Injected]
    private ISimpleAuthorizedUserRepository Repository { get; } = default!;
}

If you call this method in an authorized session it should automatically detect the context user and create a new entry in the default role in your database.

About DEVDEER

DEVDEER is a company from Magdeburg, Germany which is specialized in consulting, project management and development. We are very focussed on Microsoft Azure as a platform to run our products and solutions in the cloud. So all of our backend components usually runs in this environment and is developed using .NET. In the frontend area we are using react and a huge bunch of packages to build our UIs.

You can find us online:

Website

GitHub GitHub Org's stars

YouTube YouTube Channel Subscribers YouTube Channel Views

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
13.1.0 0 11/21/2025
13.0.3 128 11/19/2025
13.0.2 127 11/7/2025
13.0.1 163 10/21/2025
13.0.0 113 10/18/2025
12.0.8 168 10/15/2025
12.0.7 111 10/11/2025
12.0.6 109 10/11/2025
12.0.5 114 10/11/2025
12.0.4 180 10/7/2025
12.0.3 178 10/7/2025
12.0.2 174 10/6/2025
12.0.1 170 10/4/2025
12.0.0 113 9/27/2025
11.0.5 255 8/28/2025
11.0.4 196 8/13/2025
11.0.3 135 7/29/2025
11.0.2 135 7/29/2025
11.0.1 186 7/17/2025
11.0.0 181 7/16/2025
10.0.5 345 6/11/2025
10.0.4 151 5/30/2025
10.0.3 243 5/16/2025
10.0.2 245 5/16/2025
10.0.1 259 5/16/2025
10.0.0 201 4/11/2025
9.0.2 186 4/11/2025
9.0.1 202 3/18/2025
9.0.0 170 2/14/2025
8.1.1 187 1/6/2025
8.1.0 194 1/4/2025
8.0.1 196 12/13/2024
8.0.0 179 12/11/2024
7.7.2 447 10/27/2024
7.7.1 177 10/12/2024
7.7.0 180 10/3/2024
7.6.0 231 8/23/2024
7.5.0 267 8/2/2024
7.4.5 187 6/27/2024
7.4.4 293 6/12/2024
7.4.3 185 6/12/2024
7.4.2 174 6/12/2024
7.4.1 197 6/1/2024
7.4.0 176 6/1/2024
7.3.2 480 5/29/2024
7.3.1 202 5/29/2024
7.3.0 186 5/29/2024
7.2.2 209 5/28/2024
7.2.1 203 5/27/2024
7.2.0 186 5/27/2024
7.1.0 188 5/27/2024
7.0.2 211 5/27/2024
7.0.1 204 5/25/2024
7.0.0 186 5/24/2024
6.0.0 247 5/14/2024
5.1.0 292 5/4/2024
5.0.11 180 4/19/2024
5.0.9 356 3/11/2024
5.0.8 274 3/9/2024
5.0.7 330 2/18/2024
5.0.6 465 1/18/2024
5.0.5 617 12/25/2023
5.0.4 484 12/25/2023
5.0.3 438 12/25/2023
5.0.2 485 12/11/2023
5.0.1 454 12/10/2023
5.0.0 494 12/10/2023
4.4.8 546 10/29/2023
4.4.7 486 10/29/2023
4.4.6 524 10/29/2023
4.4.5 593 10/15/2023
4.4.4 528 10/15/2023
4.4.3 557 10/15/2023
4.4.2 523 10/13/2023
4.4.0 536 10/7/2023
4.3.1 530 9/27/2023
4.3.0 577 9/16/2023
4.2.0 620 9/14/2023
4.1.0 583 9/14/2023
4.0.8 623 9/8/2023
4.0.7 571 9/7/2023
4.0.5 600 9/6/2023
4.0.3 631 9/6/2023
4.0.2 598 9/6/2023
4.0.1 592 9/6/2023
4.0.0 604 9/6/2023
3.2.1 663 8/15/2023
3.2.0 611 8/15/2023
3.1.1 686 5/29/2023
3.1.0 700 5/29/2023
3.0.3 692 5/28/2023
3.0.2 683 5/28/2023
3.0.1 739 5/24/2023
3.0.0 689 5/24/2023
2.0.1 677 5/23/2023
2.0.0 710 5/23/2023
1.0.3 733 5/21/2023
1.0.2 689 5/21/2023
1.0.0 722 5/21/2023
0.5.4-beta 673 4/12/2023
0.5.3-beta 695 4/12/2023
0.5.2-beta 698 3/11/2023
0.5.1-beta 703 1/13/2023
0.5.0-beta 702 12/29/2022
0.4.2-beta 676 12/26/2022
0.4.1-beta 708 12/6/2022
0.4.0-beta 699 11/10/2022
0.3.2-beta 750 9/30/2022
0.3.1-beta 697 9/13/2022
0.3.0-beta 721 9/13/2022
0.2.0-beta 776 9/13/2022
0.1.4-beta 689 9/7/2022
0.1.3-beta 734 9/7/2022
0.1.2-beta 709 9/7/2022
0.1.1-beta 729 9/7/2022
0.1.0-beta 709 9/6/2022
0.0.8-beta 722 9/6/2022
0.0.7-beta 690 9/6/2022
0.0.6-beta 676 9/6/2022
0.0.3-beta 706 9/6/2022
0.0.2-beta 716 9/6/2022
0.0.1-beta 721 9/5/2022

- BREAKING: Replaced IOptions with IOptionsSnapshot.
- README is now part of the package and displayed in nuget.
- Using ValueTask<> instead of ValueTask<> as result type.
- Package updates.