MitMediator.AppAuthorize
Extension for MitMediator that simplifies authentication and authorization via basic auth or JWT bearer tokens
Install / Use
/learn @dzmprt/MitMediator.AppAuthorizeREADME
MitMediator.AppAuthorize
Extension for MitMediator that simplifies authentication and authorization via basic auth or JWT bearer tokens
- Installation for basic auth
- Installation for jwt bearer auth
- How to use
- Example of web api with jwt bearer auth
- Extension for HttpMediator
- Samples
- License
Installation for basic auth
1. Add package
# for application layer
dotnet add package MitMediator.AppAuthorize -v 10.0.0-alfa-2
# for ASP.NET projects
dotnet add package MitMediator.AppAuthorize.Web -v 10.0.0-alfa-2
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) 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 10.0.0-alfa-2
# for ASP.NET projects
dotnet add package MitMediator.AppAuthorize.Web -v 10.0.0-alfa-2
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>();
// Or/and inject IUserAuthenticatorByCode implementation
// if you won't use some code for sing-in (form sms, email, etc)
// builder.Services.AddScoped<IUserAuthenticatorByCode, UserAuthenticatorByCode>();
// 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) 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 theIUserAuthenticatorByCode.
Example of web api with jwt bearer auth by login and password
using System.Collections.Concurrent;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OpenApi;
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 (use Swashbuckle.AspNetCore and Swashbuckle.AspNetCore.SwaggerUI)
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Description = "Username: <b>test</b>, Password: <b>test</b>",
});
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = """
JWT Authorization header using the Bearer scheme. \r\n\r\n
Enter 'Bearer' [space] and then your token in the text input below.
\r\n\r\nExample: 'Bearer 12345abcdef'
""",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer"
});
options.AddSecurityRequirement(document => new OpenApiSecurityRequirement
{
[new OpenApiSecuritySchemeReference("Bearer", document)] = []
});
});
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 10.0.0-alfa-2
2. Use extension methods
// Get jwt token by login and password
var jwtToken = await httpMediator.GetJwtByPasswordAsync("test", "test", CancellationToken.None);
// Get jwt token by code and password
var jwtTokenByCode = await httpMediator.GetJwtByCodeAsync("
Related Skills
node-connect
349.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.0kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
