CodeWorks.Auth
0.0.3
See the version list below for details.
dotnet add package CodeWorks.Auth --version 0.0.3
NuGet\Install-Package CodeWorks.Auth -Version 0.0.3
<PackageReference Include="CodeWorks.Auth" Version="0.0.3" />
<PackageVersion Include="CodeWorks.Auth" Version="0.0.3" />
<PackageReference Include="CodeWorks.Auth" />
paket add CodeWorks.Auth --version 0.0.3
#r "nuget: CodeWorks.Auth, 0.0.3"
#:package CodeWorks.Auth@0.0.3
#addin nuget:?package=CodeWorks.Auth&version=0.0.3
#tool nuget:?package=CodeWorks.Auth&version=0.0.3
AuthModule
A highly flexible, pluggable authentication module for .NET APIs that supports:
- JWT bearer token authentication
- Email/password login with secure hashing
- Role and permission-based authorization via
[Authorize]and[HasPermission] - Email verification workflows
- Magic link login support
- Abstracted storage and email services for full control
Features
- ✅ Storage-agnostic: Bring your own
User,UserStore,TokenStore, andEmailSender - ✅ Secure by default: Uses ASP.NET Core Identity's password hasher and JWT best practices
- ✅ Policy-based authorization: Out of the box support for roles and custom permissions
- ✅ Plug-and-play email auth: Verification and magic link flows supported
- ✅ Ready for NuGet packaging
Installation
Add the package (once published):
Install-Package CodeWorks.Auth
Getting Started
1. Define Your User
public class AppUser : IUser
{
public string Id { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
public bool IsEmailVerified { get; set; }
public IEnumerable<string> Roles { get; set; }
public IEnumerable<string> Permissions { get; set; }
}
2. Implement Required Interfaces
IUserStore<TUser>
Manages user persistence (load/save/verify).
IUserTokenStore
Manages tokens used for email verification or magic login.
IUserEmailSender
Sends emails to users with custom logic (SMTP, SendGrid, etc.).
3. Register the Module
services.AddAuthModule<AppUser, AppUserStore>(options =>
{
options.SigningKey = Configuration["Jwt:Key"];
options.Issuer = "your-api";
options.Audience = "your-users";
options.Expiration = TimeSpan.FromHours(1);
},
new[] { "CanViewReports", "CanDeleteUsers" });
Services.AddOAuthProviders(builder.Configuration);
Services.AddScoped<IOAuthService<AppUser>, OAuthService<AppUser>>();
Usage
Login and Registration
Use IAuthService<TUser>:
await authService.RegisterAsync(user, password);
await authService.LoginAsync(email, password);
Email Verification & Magic Links
Use EmailAuthService<TUser>:
await emailAuth.RequestVerificationEmailAsync(user, "https://your.site/verify");
await emailAuth.ConfirmEmailAsync(token);
await emailAuth.RequestMagicLinkAsync(email, "https://your.site/login");
await emailAuth.RedeemMagicLinkAsync(token);
Authorization
Roles
[Authorize(Roles = "Admin")]
Permissions
[HasPermission("CanDeleteUsers")]
Email Setup
Development
For local development, use a simple log-based sender:
public class DevEmailSender : IUserEmailSender
{
private readonly ILogger<DevEmailSender> _logger;
public DevEmailSender(ILogger<DevEmailSender> logger)
{
_logger = logger;
}
public Task SendVerificationEmailAsync(IUser user, string tokenUrl)
{
_logger.LogInformation($"[DEV] Verification link for {user.Email}: {tokenUrl}");
return Task.CompletedTask;
}
public Task SendMagicLinkAsync(IUser user, string tokenUrl)
{
_logger.LogInformation($"[DEV] Magic login link for {user.Email}: {tokenUrl}");
return Task.CompletedTask;
}
}
Register it conditionally:
if (env.IsDevelopment())
{
services.AddScoped<IUserEmailSender, DevEmailSender>();
}
AuthController Example
[ApiController]
[Route("api/auth")]
public class OAuthController<TUser> : ControllerBase
where TUser : IOAuthUser, new()
{
private readonly IOAuthService<TUser> _oauthService;
private readonly SignInManager<TUser> _signInManager;
public OAuthController(
IOAuthService<TUser> oauthService,
SignInManager<TUser> signInManager)
{
_oauthService = oauthService;
_signInManager = signInManager;
}
[HttpGet("google")]
public IActionResult GoogleLogin(string returnUrl = "/")
{
var redirectUrl = Url.Action(
nameof(GoogleCallback),
new { returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(
"Google",
redirectUrl);
return Challenge(properties, "Google");
}
[HttpGet("google/callback")]
public async Task<IActionResult> GoogleCallback(string returnUrl = "/")
{
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return BadRequest(new { error = "Error loading external login info" });
}
var result = await _oauthService.HandleOAuthCallbackAsync(info);
if (!result.Success)
{
return BadRequest(new { error = result.ErrorMessage });
}
// Return token to client
return Ok(new
{
token = result.Token,
user = new
{
result.User.Id,
result.User.Email,
result.User.Roles,
result.User.ProfilePictureUrl
}
});
}
[HttpGet("facebook")]
public IActionResult FacebookLogin(string returnUrl = "/")
{
var redirectUrl = Url.Action(
nameof(FacebookCallback),
new { returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(
"Facebook",
redirectUrl);
return Challenge(properties, "Facebook");
}
[HttpGet("facebook/callback")]
public async Task<IActionResult> FacebookCallback(string returnUrl = "/")
{
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return BadRequest(new { error = "Error loading external login info" });
}
var result = await _oauthService.HandleOAuthCallbackAsync(info);
if (!result.Success)
{
return BadRequest(new { error = result.ErrorMessage });
}
return Ok(new
{
token = result.Token,
user = new
{
result.User.Id,
result.User.Email,
result.User.Roles,
result.User.ProfilePictureUrl
}
});
}
}
Production
Use a real SMTP service like MailKit to send actual emails. Here’s a starting point:
- MailKit NuGet: https://www.nuget.org/packages/MailKit
- Example usage guide: https://github.com/jstedfast/MailKit/blob/master/FAQ.md#sending-messages
- SMTP via Cloudflare guide: Use Your Domain's Email via SMTP
You can also configure third-party providers such as:
OAuth Provider Setup
Google OAuth:
- Go to Google Cloud Console
- Create OAuth 2.0 credentials
- Add authorized redirect URI: https://yourdomain.com/api/auth/google/callback
Facebook OAuth:
- Go to Facebook Developers
- Create a new app
- Add Facebook Login product
- Add redirect URI: https://yourdomain.com/api/auth/facebook/callback
- Install Required NuGet Packages:
dotnet add package Microsoft.AspNetCore.Authentication.Google
dotnet add package Microsoft.AspNetCore.Authentication.Facebook
- Add OAuth Configuration to appsettings.json
{
"Authentication": {
"Google": {
"ClientId": "your-google-client-id",
"ClientSecret": "your-google-client-secret"
},
"Facebook": {
"AppId": "your-facebook-app-id",
"AppSecret": "your-facebook-app-secret"
}
},
"Jwt": {
"Key": "your-signing-key",
"Issuer": "your-api",
"Audience": "your-users"
}
}
Extensibility
IUser- your user modelIUserStore<TUser>- storage logicIUserTokenStore- token persistenceIUserEmailSender- email transport
Roadmap
- Multi-factor authentication
- TOTP support
License
MIT or commercial dual-license (TBD).
| Product | Versions 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. |
-
net9.0
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 9.0.3)
- Microsoft.AspNetCore.Identity (>= 2.3.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.