An ASP.NET Core authentication handler for the HashBack protocol. Drop this into a web service project to accept Authorization: HashBack ... headers using the standard ASP.NET Core authentication pipeline - [Authorize], HttpContext.User, WWW-Authenticate challenges and all.
This package is a thin ASP.NET Core adapter around billpg.HashBackCore, which does the actual protocol work (parsing, hashing, policy checks).
Not yet published to NuGet. Clone this repository and add a project reference to billpg.HashBackAspNetCore.csproj.
In Program.cs:
builder.Services.AddAuthentication(HashBackAuthenticationDefaults.AuthenticationScheme)
.AddHashBack(options =>
{
/* Required: which Host value(s) this server accepts. */
options.Policy.RequireHost("myservice.example");
/* Required: map a Verify URL to the identity of the caller who owns it. */
options.Policy.SetSyncIdentifyUser(verify => LookUpUserForVerifyUrl(verify));
/* Recommended: replay protection, and how much clock drift to tolerate. */
options.Policy.RequireNowWindow(30);
options.Policy.RequireUnusNotReused(TimeSpan.FromMinutes(5));
/* Optional: shown in the WWW-Authenticate challenge header. */
options.Realm = "myservice.example";
});
builder.Services.AddAuthorization();
// ...
app.UseAuthentication();
app.UseAuthorization();Then protect an endpoint the normal ASP.NET Core way:
app.MapGet("/hello", (ClaimsPrincipal user) => $"Hello {user.FindFirst(ClaimTypes.NameIdentifier)!.Value}!")
.RequireAuthorization();- Parses and validates the incoming
Authorizationheader usingHashBackRequest. - Runs your configured
HashBackPolicy(host, time window, replay, user identification). - Downloads the verification hash itself, using a built-in
HttpClient-based fetcher (no redirects followed, short timeout) - unless you setoptions.UseDefaultVerificationHashFetcher = falseand assignoptions.Policy.OnGetVerificationHashyourself, which is recommended if you need stricter protections such as SSRF-safe IP filtering (seeDemoService's ownHttpGetterfor an example of that level of hardening). - On success, builds a
ClaimsPrincipalcarrying the identified user as aClaimTypes.NameIdentifierclaim. - On failure, issues a
WWW-Authenticate: HashBackchallenge header (with an optionalrealm) alongside the401response, per the HashBack specification.
- It doesn't cache successful authentications behind a cookie or bearer token. The HashBack exchange is relatively expensive, so most services will want to issue a short-lived cookie or token after the first successful authentication and accept that on subsequent requests instead - that's application-specific and left to you. (
DemoService'sHelloControllershows one way to do this.)