HowlDev.Web.Authentication.AccountAuth
4.0.2
Prefix Reserved
dotnet add package HowlDev.Web.Authentication.AccountAuth --version 4.0.2
NuGet\Install-Package HowlDev.Web.Authentication.AccountAuth -Version 4.0.2
<PackageReference Include="HowlDev.Web.Authentication.AccountAuth" Version="4.0.2" />
<PackageVersion Include="HowlDev.Web.Authentication.AccountAuth" Version="4.0.2" />
<PackageReference Include="HowlDev.Web.Authentication.AccountAuth" />
paket add HowlDev.Web.Authentication.AccountAuth --version 4.0.2
#r "nuget: HowlDev.Web.Authentication.AccountAuth, 4.0.2"
#:package HowlDev.Web.Authentication.AccountAuth@4.0.2
#addin nuget:?package=HowlDev.Web.Authentication.AccountAuth&version=4.0.2
#tool nuget:?package=HowlDev.Web.Authentication.AccountAuth&version=4.0.2
HowlDev.Web.Authentication
Read the docs at this link.
This authenticator provides an AuthService, an IdentityMiddleware, and some helpful parameters and extensions for minimalAPIs. This is a naive authenticator that handles an account/password combo.
This is the README for both the AccountAuth and Middleware package.
Recommended API layout in Program.cs:
builder.AddAuthService();
builder.Services.AddLogging();
var app = builder.Build();
app.UseAccountIdentityMiddleware(MiddlewareLocation.Headers, options => {
// Apply Path, Whitelist, Timespan, or Logging objects here
// Configure how Headers behave and which headers you read from
});
app.UseRouting();
// ... rest of endpoints
Important headers:
Account-Auth-Account: {{Username}}
Account-Auth-ApiKey: {{Key}}
To enable logs, your appsettings.json should look like this:
"Logging": {
"LogLevel": {
"Default": "Information",
"HowlDev.Web.Authentication": "Trace" // Or Debug, Information, Warn, Error, etc.
// .. any others here
}
},
You can check the XML comments for my extension method and the AccountInfo parameter, and you can use the source repository API as a sample usage.
SQL
This SQL is a requirement for the Service to work properly. Since I'm using Dapper/NpgSql, you need a Postgres database with the following SQL tables:
CREATE TABLE "HowlDev.User" (
id UUID PRIMARY KEY,
accountName varchar(200) UNIQUE NOT NULL,
passHash varchar(200) NOT NULL,
role int NOT NULL
);
CREATE TABLE "HowlDev.Key" (
id int PRIMARY KEY GENERATED ALWAYS AS IDENTITY NOT NULL,
accountId varchar(200) references "HowlDev.User" (accountName) NOT NULL,
apiKey varchar(20) NOT NULL,
validatedOn timestamp NOT NULL
);
This can be added to as much as you like to encode more information (for example in the User table), but this is what's required to make my auth work.
Upcoming Features
A few more features are coming before I consider the library done. (This is a somewhat old list; the library is available to be used but I'll be adding a lot more to it whenever I can).
- Integration tests with the Docker Compose to run full auth flows
- Test throwing errors and what you should expect as a return value
- Endpoint filters that take place of IdentityMiddleware for projects that only need to secure a few endpoints
- This includes extracting that logic into an external class, which could be read by you as well
- A default map for signin, signout, and change password (this may be expanded later)
- Ex. mapping some default (optional) GET and POST requests to keep them out of your way
- This would include both a C# and JS client package for immediate usage in Blazor (C#) and any JS app
- Change AuthService implementation to:
- Enable/disable caching of roles and GUID
- Write code to enable/disable caching of API keys
- Instead of adjusting cache directly, should just invalidate it
- This would include a rewrite of the singleton registration to match the
UseAccountIdentityMiddlewarefunction - (with long-term-planning 1 below): set a TimeSpan which will clear the cache asynchronously
- Mhmm.. instead of having
TryAccountInfoand the method that you need to call to validate it, I could just combine the logic into that class and have it do everything it needs to do before reaching out... Version 4.1 thing.
Changelog
4.0.1-2 & 2.0.1-2 (7/7/26)
- Added more Trace logs for debugging inside TrySetAccountInformation
- Changed internal logic in that method from
__ is not nulltostring.IsNullOrWhiteSpace(___). - 0.2
- Fixed bug with setting context multiple times (which would throw crashing errors)
- and some more logs
4.0.0 & 2.0.0 (6/30/26)
BREAKING CHANGE: UseAccountIdentityMiddleware now takes in a new first parameter so I have a path for growth without major version changes. The default is Headers, which is the same system being used for the last year.
- Just as a roadmap, I plan on including options for Cookies (which are more secure against XSS) and an OIDC validation, which will just use Microsoft's OIDC connector, but still maintain the same AccountInfo interface and provide a new injectable class to get relevant OIDC information.
Optimized some IAuthMiddleware database calls to not throw errors and instead return defaults through Dapper (which I think save around 1.5 microseconds by not having to throw and catch).
- This includes a new wrapper type, Result<T>, which just says the inner thing may be null if the outer IsValid flag is not true. Simple to use and check.
Included a pair of functions; the
TryAccountInfoclass which is sort of a code overload for a Result type, and the new endpoint filterTrySetAccountInformationwhich looks for a key and validates it (providing you with the standard AccountInfo information), or fails and just falls through.- In one of my projects, I wanted to have one endpoint I could call with or without authentication, and it would either show me a public version or something specific to my user.
- This only applies to endpoints that are bypassed by one of the parameters passed to the Middleware. There are various mechanisms to help you configure this correctly (by which I mean it will throw errors when you use it incorrectly). These are all using Debug flags though so it should be just as fast in production.
Provided an option to configure the inner Argon options and a static method to benchmark it (see
Program.csin the TestingAPI for sample usage). This will make the hashes more secure/configured to the machine you're running on.3.1.0 (3/17/26)
Added two new methods to the AuthService:
- AccountNameExistsAsync, which returns a bool as to if an account name exists. They swallow errors, so it can be a helpful check (at the expense of calling the DB again). This has overloads for strings (accountName) and GUID values.
- UpdateAccountNameAsync, allowing a GUID and new string to be assigned to that account. Because of how it works, it requires a signout (at least, my testing required it), so it by default signs you out completely, makes the update, then clears the cache of old values (if they exist).
1.2.0 & 3.0.2 (2/26/25)
Version bump, adding to my new organization on GitHub.
Updated formatting.
- Middleware now has slightly more optimal logging statements if logging is disabled.
1.1.0 (12/26/25)
Middleware configuration now enables Regex paths for more general endpoints (such as ones with arbitrary IDs)
- Configure in the options configuration as RegexPaths
You can now update the headers for account and api key instead of the defaults. Those defaults will apply, but you can now overwrite them to whatever you wish.
3.0.1 (12/16/25) and 1.0.2
Extracted dependency for middleware to an internal interface so multiple authentication types can be based off of it
Inverted dependency so that AccountAuth now depends on Middleware, not the other way around
Oh yeah, this is the major release. I figured out a pipeline, so now I can make new packages faster.
3.0.3 - Beta (12/15/25)
Removed the Logging option from the configuration (this should be left to you anyways).
3.0.2 - Beta (11/22/25)
Added a
DisableHeaderInfo(default: false) config option that removes the header error message, instead just saying that you don't have the headers needed. This is good for production and for error messages shown to users.3.0.1 - Beta (11/19/25)
Changed into a concurrent dictionary for the lookups
3.0 - Beta (9/18/25)
Version 3 came way faster than I wanted. I'll be sitting in beta for a few months so I reduce the chance of me spamming major versions. I intended to keep it low..
I need to change major versions because I need to update the SQL for initialization. I knew that I should for some time, but our project has determined that we need salted hashes for the password values. I already have the tools needed to implement it, but I just.. didn't, for the major version I implemented a week ago.
As mentioned, I'll be in beta (and likely releasing bug-fix versions whenever we need an update), then once we've been using it for long enough, I imagine I can release a more complete version 3.0.
The goals I intend to complete are listed above in the Upcoming Features heading. They will be moved out of there into the bugfix patches whenever I complete a new version. Below are the ones I've done for this version.
Salted hashes (Invalidates all prior hashes in a table)
Removed some features of String Helper
Added minor logging to the three async Search functions
2.0.1 (9/17/25)
Added a GetCurrentSessionCount method to get the current number of keys (not entirely validated) in the table.
Also of note, the non-Async methods have not been as thoroughly tested as the Async methods.
2.0 (9/10/25)
A few additional features have been added. The middleware configuration now has a Logging system, turned off by default. There is an internal (but accessible) class called DbConnector which helps encapsulate Dapper queries correctly.
The AuthService now has Async and sync methods by default. I believe logging will be added to that at a future time as well, maybe with it's own configuration system.
Please see the docs (and scroll to the bottom) for new version 2.0 functions and more specificity.
This is still under test and subject to be bugfixed within the next few weeks of release. We're using it in a current project and hopefully will run into all the problems ourselves.
2.0 - Alpha (8/22/25)
Version 2 came much faster than I wanted.
I started to actually use this in a project. I was building an SPA and I generated a few items that made concurrent calls to the API. The AuthService broke because the connection was trying to be shared, and after many discussions with ChatGPT (and internal crying), I built this Alpha version to test. All AuthService method names and return types have been adjusted to be async.
It includes a DbConnector class to inject and get new async managed connections. We will see if
this fixes everything; assuming so, for the final release of 2.0, I will try and figure out non-async
methods.
This no longer requires an IDbConnection DI injection, but it looks like all other notes above
maintain. I'll adjust those with version-specific updates once 2.0 comes out in full release.
1.2 (7/7/25)
- AuthService new Accounts now have a place to set a default Role number.
- Generated a number of Endpoint filters to help with clean authorization. A few code examples will be provided below (see wiki for more).
- IdentityMiddleware now passes the Account through
HttpContext.Items. - .csproj has removed the "Microsoft.AspNetCore.Http" reference in favor of the "Microsoft.AspNetCore.App" framework
app.MapGet(...).RequireRoleIsEqualTo(3);
app.MapGet(...).RequireRoleIsGreaterThan(2, HttpStatusCode.Forbidden);
app.MapGet(...).RequireRoleIsLessThan(4, 403);
app.MapGet(...).RequireRoleIs(i => i > 4); // Obviously this function can be done in other ways, but this shows how it can work.
These could also be used as simpler methods to return custom error codes depending on the role of the user.
1.1 (7/6/25)
AccountInfo now includes Role property, making role checking much cleaner. Should've done this from the start.
1.0 (!) (6/20/25)
Attempted writing some tests, will not worry about that for the .0 release. Check back in to the repo to check test status.
0.9.0 (6/19/25)
BREAKING CHANGES
- Changed DB to include UUID's instead of sequential ints
- Otherwise simplified the database schema to only include necessities (and roles, I think roles are important)
- Entirely removed MiddlewareConfig interface, moved it to a new extension method for the app (see below)
Included a new class to more easily get auth information into your endpoints. Use the AccountInfo parameter!
Added a few AuthService methods to retrieve Role and Guid information
Added more methods to update values within the database
How to use the new middleware setup:
app.UseAccountIdentityMiddleware(options => {
options.Paths = ["/users", "/user", "/user/signin"];
options.Whitelist = "/data";
options.ExpirationDate = new TimeSpan(30, 0, 0, 0);
options.ReValidationDate = new TimeSpan(5, 0, 0, 0);
});
Any option not configured has defaults, so you can remove the lambda entirely (though for various reasons, I don't recommend doing that), or you can just configure the options you want.
Sample of the AccountInfo parameter for minimal endpoints:
app.MapGet("/user/guid", (AccountInfo info) => info.Guid);
app.MapGet("/user/role", (AccountInfo info) => info.Role);
0.8.4 (5/19/25)
Removed last bugfix.
Updated information on this Readme
BREAKING CHANGE: IIDMiddlewareConfig now has an additional
Whitelistproperty, actually enabling SPAs.0.8.2 (5/19/25)
IdentityMiddleware does not enforce path restrictions to anything in /assets, allowing for SPAs.
0.8.1 (5/16/25)
GetUser now takes and checks an AccountName instead of an Email.
0.8 (5/15/25)
Init
| Product | Versions 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 was computed. 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. |
-
net8.0
- Dapper (>= 2.1.66)
- HowlDev.Web.Authentication.Middleware (>= 2.0.2)
- HowlDev.Web.Helpers.DbConnector (>= 1.0.1)
- Konscious.Security.Cryptography.Argon2 (>= 1.3.1)
- Npgsql (>= 9.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.