MitMediator.AppAuthorize.Web 9.0.0-alfa-3

This is a prerelease version of MitMediator.AppAuthorize.Web.
dotnet add package MitMediator.AppAuthorize.Web --version 9.0.0-alfa-3
                    
NuGet\Install-Package MitMediator.AppAuthorize.Web -Version 9.0.0-alfa-3
                    
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="MitMediator.AppAuthorize.Web" Version="9.0.0-alfa-3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MitMediator.AppAuthorize.Web" Version="9.0.0-alfa-3" />
                    
Directory.Packages.props
<PackageReference Include="MitMediator.AppAuthorize.Web" />
                    
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 MitMediator.AppAuthorize.Web --version 9.0.0-alfa-3
                    
#r "nuget: MitMediator.AppAuthorize.Web, 9.0.0-alfa-3"
                    
#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 MitMediator.AppAuthorize.Web@9.0.0-alfa-3
                    
#: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=MitMediator.AppAuthorize.Web&version=9.0.0-alfa-3&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=MitMediator.AppAuthorize.Web&version=9.0.0-alfa-3&prerelease
                    
Install as a Cake Tool

Build and Test NuGet .NET 9.0

MitMediator.AppAuthorize

Extension for MitMediator that simplifies authentication and authorization via basic auth or JWT bearer tokens

Installation for basic auth

1. Add package

# for application layer
dotnet add package MitMediator.AppAuthorize -v 9.0.0-alfa-3

# for ASP.NET projects
dotnet add package MitMediator.AppAuthorize.Web -v 9.0.0-alfa-3

2. Inject services for application layer

// Register handlers and IMediator
services.AddMitMediator();

// Register authorization pipe
services.AddAppAuthorize();

// Inject IUserAuthenticator implementation
builder.Services.AddScoped<IUserAuthenticator, UserAuthenticator>();

3. Inject services for web layer

// Add default auth context (or implement and inject IAuthenticationContext)
builder.Services.AddDefaultAuthContext();

4. Use basic auth middleware

app.UseBasicAuth();

5. (Optional) Add swagger security definition

builder.Services.AddSwaggerGen(options => options.AddBasicAuth());

6. (Optional) Use middleware to handle auth exceptions

// Unauthorized - 401, Forbidden - 403
app.UseAuthException();

Installation for jwt bearer auth

1. Add package

# for application layer
dotnet add package MitMediator.AppAuthorize -v 9.0.0-alfa-3

# for ASP.NET projects
dotnet add package MitMediator.AppAuthorize.Web -v 9.0.0-alfa-3

2. Inject services for application layer

// Register handlers and IMediator
services.AddMitMediator();

// Register authorization pipe
services.AddAppAuthorize();

// Inject IUserAuthenticator implementation
builder.Services.AddScoped<IUserAuthenticator, UserAuthenticator>();

// Inject IRefreshTokenRepository implementation
builder.Services.AddScoped<IRefreshTokenRepository, RefreshTokenRepository>();

3. Inject services for web layer

// Add default auth context (or implement and inject IAuthenticationContext)
builder.Services.AddDefaultAuthContext();

// Add auth services and configure TokenValidationParameters
builder.Services.AddJwtAuthServices("your-secure-key-here");

4. Map jwt endpoints

app.MapJwtAuthApi();

5. (Optional) Add swagger security definition

builder.Services.AddSwaggerGen(options => options.AddJwtAuth());

6. (Optional) Use middleware to handle auth exceptions

// Unauthorized - 401, Forbidden - 403
app.UseAuthException();

How to use

By default, all requests require authorization

To customize a required role or tenant, use attribute AppAuthorizeAttribute

[AppAuthorize(["SomeRoleName", "SecondRoleName"], ["TestTenantId"])]
public class GetTestRequest : IRequest { }

To allow anonymous access to a request, use attribute AppAllowAnonymousAttribute

[AppAllowAnonymous]
public class GetTestRequest : IRequest { }

To get access to user info in the application layer use IAuthenticationContext

public class GetAuthStatusQueryHandler(IAuthenticationContext authenticationContext)
    : IRequestHandler<GetAuthStatusQuery, bool>
{
    public ValueTask<bool> HandleAsync(GetAuthStatusQuery request, CancellationToken cancellationToken) =>
        ValueTask.FromResult(authenticationContext.IsAuthenticated);
}

You can add a superuser role for an admin or the system:

    services.AddAppAuthorize("admin");

Instead of a refresh token key, you may use any alternative code, such as a one-time code received via SMS or email.
To support this logic, implement the IRefreshTokenRepository interface with appropriate handling and validation of such codes.

Example of web api with jwt bearer auth

using System.Collections.Concurrent;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OpenApi.Models;
using MitMediator;
using MitMediator.AppAuthorize;
using MitMediator.AppAuthorize.Domain;
using MitMediator.AppAuthorize.Web;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddHttpContextAccessor();

// Add MitMediator
builder.Services.AddMitMediator();

// Add default auth context
builder.Services.AddDefaultAuthContext();
// Inject IUserAuthenticator implementation
builder.Services.AddScoped<IUserAuthenticator, UserAuthenticator>();
// Inject IRefreshTokenRepository implementation
builder.Services.AddScoped<IRefreshTokenRepository, RefreshTokenRepository>();
// Authorization pipline behavior
builder.Services.AddAppAuthorize();
// Auth and jwt services
builder.Services.AddJwtAuthServices("key1234567890098765433123123123232323");

// Add jwt auth to swagger
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Description = "Username: <b>test</b>, Password: <b>test</b>",
    });
    options.AddJwtAuth();
});

var app = builder.Build();

// Handle auth exceptions(Forbidden, Unauthorized)
app.UseAuthException();

app.UseSwagger();
app.UseSwaggerUI();

// Map jwt endpoints
app.MapJwtAuthApi();

app.MapGet("/auth-status",
    async ([FromServices] IMediator mediator,
            CancellationToken cancellationToken) =>
        await mediator.SendAsync<GetAuthStatusQuery, bool>(new GetAuthStatusQuery(), cancellationToken));


app.MapGet("/test",
    async ([FromServices] IMediator mediator,
            CancellationToken cancellationToken) =>
        await mediator.SendAsync(new GetTestQuery(), cancellationToken));

app.Run();


// Implement IUserAuthenticator for sign-in logic
public class UserAuthenticator : IUserAuthenticator
{
    public ValueTask<UserInfo> AuthByPasswordAsync(string username, string password,
        CancellationToken cancellationToken)
    {
        if (username == "test" && password == "test")
            return ValueTask.FromResult(new UserInfo("testId", "test"));

        throw new ForbiddenException();
    }
}

// Implement IRefreshTokenRepository
public class RefreshTokenRepository : IRefreshTokenRepository
{
    private static readonly ConcurrentDictionary<string, RefreshToken> _concurrentDictionary = new();

    public ValueTask<RefreshToken> AddAsync(RefreshToken refreshToken, CancellationToken cancellationToken)
    {
        refreshToken.RefreshTokenKey = Guid.NewGuid().ToString();
        if (!_concurrentDictionary.TryAdd(refreshToken.RefreshTokenKey, refreshToken))
        {
            throw new Exception("Add refresh token error.");
        }

        return ValueTask.FromResult(refreshToken);
    }

    public ValueTask<RefreshToken?> GetOrDefaultAsync(string RefreshTokenKey, CancellationToken cancellationToken)
    {
        _concurrentDictionary.TryGetValue(RefreshTokenKey, out var value);
        return ValueTask.FromResult(value);
    }

    public ValueTask RemoveAsync(RefreshToken entity, CancellationToken cancellationToken)
    {
        _concurrentDictionary.TryRemove(entity.RefreshTokenKey, out var value);
        return ValueTask.CompletedTask;
    }

    public ValueTask<UserInfo?> GetUserInfoByTokenOrDefaultAsync(RefreshToken refreshToken, CancellationToken cancellationToken)
    {
        _concurrentDictionary.TryGetValue(refreshToken.RefreshTokenKey, out var token);
        if (token is null)
        {
            return ValueTask.FromResult<UserInfo?>(null);
        }
        
        return ValueTask.FromResult<UserInfo?>(new UserInfo(token.UserId, token.UserId));
    }
}


[AppAllowAnonymous]
public class GetAuthStatusQuery : IRequest<bool>;

public class GetAuthStatusQueryHandler(IAuthenticationContext authenticationContext)
    : IRequestHandler<GetAuthStatusQuery, bool>
{
    public ValueTask<bool> HandleAsync(GetAuthStatusQuery request, CancellationToken cancellationToken) =>
        ValueTask.FromResult(authenticationContext.IsAuthenticated);
}

public class GetTestQuery : IRequest;

public class GetTestQueryHandler : IRequestHandler<GetTestQuery>
{
    public ValueTask<Unit> HandleAsync(GetTestQuery request, CancellationToken cancellationToken) =>
        ValueTask.FromResult(Unit.Value);
}

Extension for HttpMediator

Extension for MitMediator.AutoApi.HttpMediator that enables JWT Bearer authorization

1. Add package

dotnet add package MitMediator.AppAuthorize.ClientMediator -v 9.0.0-alfa

2. Use extension methods

// Get jwt token by login and password
var jwtToken = await httpMediator.GetJwtBearerTokenAsync("test", "test", CancellationToken.None);

// Get jwt token by refresh token key
var jwtByRefreshToken = await httpMediator.GetJwtBearerTokenByRefreshAsync(jwtToken.UserId, jwtToken.RefreshToken, CancellationToken.None);

See more samples

Product Compatible and additional computed target framework versions.
.NET 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
9.0.0-alfa-3 251 9/16/2025
9.0.0-alfa 85 9/5/2025

- Added superuser role
- Changerd TenantId claim name to "https://schemas.microsoft.com/identity/claims/tenantid"