RossWright.MetalGuardian.Server 1.0.0-alpha2

This is a prerelease version of RossWright.MetalGuardian.Server.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package RossWright.MetalGuardian.Server --version 1.0.0-alpha2
NuGet\Install-Package RossWright.MetalGuardian.Server -Version 1.0.0-alpha2
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="RossWright.MetalGuardian.Server" Version="1.0.0-alpha2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add RossWright.MetalGuardian.Server --version 1.0.0-alpha2
#r "nuget: RossWright.MetalGuardian.Server, 1.0.0-alpha2"
#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.
// Install RossWright.MetalGuardian.Server as a Cake Addin
#addin nuget:?package=RossWright.MetalGuardian.Server&version=1.0.0-alpha2&prerelease

// Install RossWright.MetalGuardian.Server as a Cake Tool
#tool nuget:?package=RossWright.MetalGuardian.Server&version=1.0.0-alpha2&prerelease

MetalGuardian

by Ross Wright

Copyright 2023 Pross Co. All Rights Reserved.

Description

Metal Guardian is a library to help implement authentication for HTTP connections using JWT and serve as a lightweight and flexible alternative to ASP.NET Identity. Metal Guardian is even more powerful when combined with MetalNexus.

Server Setup

On your ASP.NET server, the Metal Guardian service requires a appsettings to be added to the configuration:

  "MetalGuardian": {
    "JwtIssuer": "https://rosswright.com", // fill in your company url
    "JwtAudience": "https://testapp.rosswright.com", // fill in your app client url
    "JwtIssuerSigningKey": "sJKLh678hl_jkh5", // fill in your app's signing key - a ver long random alphanumeric string
    "RefreshTokenExpireMins": 10080, // The number of minutes it should take a refresh token to expire, 10080 is 1 week
    "JwtAccessTokenExpireMins": 1440, // The number of minutes it should take an access token to expire, 1440 is 1 day
    "ForgotPasswordExpireMins": 15, // The number of minutes it should take a single-use forgot password code to expire
  }

The library is initialized in program.cs by calling: builder.AddMetalGuardian()

The Metal Guardian relies on 2 services being present that you must implement:

IAuthUserRepository (Required) - which is a repository for users and refresh tokens likely backed by a database of your choice.

namespace RossWright.MetalGuardian.Server;

public interface IAuthUserRepository
{
    Task<IAuthUser?> GetUser(string userIdentity, CancellationToken cancellationToken, Func<IAuthUser, bool>? updateUser = null);
    Task AddRefreshToken(Guid userId, string refreshToken, CancellationToken cancellationToken);
    Task<IAuthUser?> RefreshToken(Guid userId, string refreshToken, CancellationToken cancellationToken);
    Task ClearToken(Guid userId, string refreshToken, CancellationToken cancellationToken);
}

The user entities must implement IAuthUser.

namespace RossWright.MetalGuardian.Server;

public interface IAuthUser
{
    Guid UserId { get; }
    string Name { get; }
    string PasswordSalt { get; set; }
    string PasswordHash { get; set; }
    object[] Roles { get; }
    IEnumerable<(string, string)>? AdditionalClaims { get; }
    public string? ForgotPasswordCodeSalt { get; set; }
    public string? ForgotPasswordCodeHash { get; set; }
    public DateTimeOffset? ForgotPasswordCodeExpiration { get; set; }
}

IForgotPasswordSender - communicates a password reset code to a user using whatever email or sms (or other) mechanism you want.

namespace RossWright.MetalGuardian.Server;

public interface IForgotPasswordSender
{
    Task Send(IAuthUser user, string code, CancellationToken cancellationToken);
}

These services must be registered as scoped services, but can registered via the AddMetalGuardian call with builder.AddMetalGuardian<TAuthUserRepositoryImpl>(); if the implementation also implements IForgotPasswordSender, it will be registered for that service. Otherwise, no ForgotPasswordSender will be registered by the method. To register separate implementations for each service, you can use: builder.AddMetalGuardian<TAuthUserRepositoryImpl, TForgotPasswordSenderImpl>(); which will register the implementation for each service for you. Notew that these are convenience overrides simply to help keep your program.cs tidy. You can register them yourself, perhaps using MetalInjection.

All of this enables you to inject the IMetalGuardianService:

namespace RossWright.MetalGuardian.Server;

public interface IMetalGuardianService
{
    Task<AuthenticationTokens> Login(string userIdentity, string password, CancellationToken cancellationToken);
    Task Logout(AuthenticationTokens tokens, CancellationToken cancellationToken);
    Task<AuthenticationTokens> Refresh(AuthenticationTokens tokens, CancellationToken cancellationToken);
    Task GetForgotPasswordCode(string userIdentifier, CancellationToken cancellationToken);
    Task<AuthenticationTokens> LoginWithCode(string userIdentifier, string code, CancellationToken cancellationToken);
}

You can implment a controller for your front end that simply calls the Metal Guardian Service to handle all these concerns. You can decorate your controllers and actions with [Authorize] attributes as usual and access information about the logged in user via the Controller.User property or by injecting IHttpContextAccessor as normal.

On the Blazor client side, in program.cs call builder.Services.AddMetalGuardianHttpClient({baseAddress}) where baseAddress is the base url of your server. Now when you inject an HttpClient, it will be setup with security. You can support connections to multiple servers by specifying a connection name builder.Services.AddMetalGuardianHttpClient({baseAddress}, {connectionName}) which you can then consume by injecting the IHttpClientFactory and calling CreateClient on that service passing the same connectionName.

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. 
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
1.0.0-alpha6.6 44 6/24/2024
1.0.0-alpha6.5 36 6/23/2024
1.0.0-alpha6.4 34 6/13/2024
1.0.0-alpha6.3 38 6/12/2024
1.0.0-alpha6.2 36 6/12/2024
1.0.0-alpha6.1 42 5/30/2024
1.0.0-alpha6 47 5/30/2024
1.0.0-alpha5.2 45 5/25/2024
1.0.0-alpha5.1 57 5/16/2024
1.0.0-alpha5 52 4/23/2024
1.0.0-alpha4.4 104 4/4/2024
1.0.0-alpha4.2 51 4/4/2024
1.0.0-alpha4.1 56 4/4/2024
1.0.0-alpha4 40 4/4/2024
1.0.0-alpha3.3 51 4/2/2024
1.0.0-alpha3.2 50 4/1/2024
1.0.0-alpha3.1 51 4/1/2024
1.0.0-alpha3 53 4/1/2024
1.0.0-alpha2 61 3/30/2024
1.0.0-alpha1 47 3/23/2024