ForgeTrust.AppSurface.Auth.Testing
0.2.0-preview.2
dotnet add package ForgeTrust.AppSurface.Auth.Testing --version 0.2.0-preview.2
NuGet\Install-Package ForgeTrust.AppSurface.Auth.Testing -Version 0.2.0-preview.2
<PackageReference Include="ForgeTrust.AppSurface.Auth.Testing" Version="0.2.0-preview.2" />
<PackageVersion Include="ForgeTrust.AppSurface.Auth.Testing" Version="0.2.0-preview.2" />
<PackageReference Include="ForgeTrust.AppSurface.Auth.Testing" />
paket add ForgeTrust.AppSurface.Auth.Testing --version 0.2.0-preview.2
#r "nuget: ForgeTrust.AppSurface.Auth.Testing, 0.2.0-preview.2"
#:package ForgeTrust.AppSurface.Auth.Testing@0.2.0-preview.2
#addin nuget:?package=ForgeTrust.AppSurface.Auth.Testing&version=0.2.0-preview.2&prerelease
#tool nuget:?package=ForgeTrust.AppSurface.Auth.Testing&version=0.2.0-preview.2&prerelease
ForgeTrust.AppSurface.Auth.Testing
ForgeTrust.AppSurface.Auth.Testing is a test-only ASP.NET Core authentication harness for proving AppSurface auth behavior.
Use this package in integration test projects when a consumer needs deterministic personas, real ASP.NET Core policy evaluation, AppSurface auth outcomes, and ProblemDetails assertions without writing a one-off fake authentication handler.
Release Guidance
AppSurface ships as a coordinated package family. Before installing this package from a prerelease feed, check the package chooser and release hub for current release risk, migration guidance, and readiness.
Use the AppSurface Auth adoption ladder when choosing between Auth.Testing, DevAuth, OIDC, and host-owned ASP.NET Core authentication.
Quickstart: WebApplicationFactory Personas
Install the package in a test project:
dotnet add package ForgeTrust.AppSurface.Auth.Testing --prerelease
Configure the factory with explicit personas:
using System.Security.Claims;
using ForgeTrust.AppSurface.Auth.Testing;
await using var baseFactory = new WebApplicationFactory<Program>();
await using var factory = baseFactory.WithAppSurfaceTestAuth(options =>
{
options.SubjectClaimType = "sub";
options.AddPersona(
"operator",
"operator-1",
[new Claim("role", "operator")]);
options.AddPersona(
"viewer",
"viewer-1",
[new Claim("role", "viewer")]);
});
using var operatorClient = factory.CreateAppSurfaceClient("operator");
using var response = await operatorClient.GetAsync("/operator-work");
No persona selection means the request is anonymous:
using var anonymousClient = factory.CreateClient();
using var response = await anonymousClient.GetAsync("/operator-work");
For request-level switching, apply the helper to one message:
using var request = new HttpRequestMessage(HttpMethod.Get, "/operator-work")
.WithAppSurfaceTestPersona("viewer");
using var client = factory.CreateClient();
using var response = await client.SendAsync(request);
CreateAppSurfaceClient(...) validates the persona before sending a request. WithAppSurfaceTestPersona(...)
is intentionally transport-only, so an unknown request-level persona is detected by the server-side test handler and
reported as an AppSurface setup failure instead of being treated as anonymous.
Service Registration API
Use the lower-level registration when the test host is not built with WebApplicationFactory:
builder.Services.AddAppSurfaceTestAuth(options =>
{
options.SchemeMode = AppSurfaceTestAuthSchemeMode.NamedScheme;
options.SubjectClaimType = "sub";
options.AddPersona("operator", "operator-1", [new Claim("role", "operator")]);
});
AddAppSurfaceTestAuth(...) composes ForgeTrust.AppSurface.Auth.AspNetCore, creates an immutable persona registry, and registers a test authentication scheme when the selected SchemeMode enables it. Normal ASP.NET Core authorization policies still run. AppSurface still maps the result through AppSurfaceAuthResult and RequireSurfacePolicy(...) still renders AppSurface-shaped ProblemDetails for API callers.
If the host registered a custom IAppSurfaceAspNetCorePolicyEvaluator before calling AddAppSurfaceTestAuth(...), Auth.Testing decorates that evaluator instead of replacing it. The host evaluator continues to own policy evaluation and result mapping; Auth.Testing only adds the test-only unknown-persona diagnostic.
Scheme Modes
| Mode | Use when | Behavior |
|---|---|---|
DefaultScheme |
You want the shortest WebApplicationFactory test setup. | Registers AppSurface.Test and makes it the default authenticate, challenge, and forbid scheme. |
NamedScheme |
Your policies opt in to the test scheme by name. | Registers the scheme without changing host defaults. |
NoDefault |
You need to prove the harness does not take over host defaults. | Registers the persona registry without registering the test scheme. Policies follow normal ASP.NET Core default-scheme behavior. |
The default scheme name is AppSurface.Test. Set SchemeName only when the test host needs a different explicit scheme name.
Subject Mapping
By default, the harness emits ClaimTypes.NameIdentifier, which preserves the first default subject mapping used by ForgeTrust.AppSurface.Auth.AspNetCore. Set SubjectClaimType only when the host policy proof uses a different stable subject claim such as sub.
SubjectClaimType affects only the generated test principal and the AppSurface subject mapping. It does not map display names, emails, permissions, scopes, sessions, or app-user provisioning.
Assertions
The assertion helpers do not depend on xUnit, NUnit, or MSTest:
AppSurfaceAuthTestAssert.HasOutcome(
result,
AppSurfaceAuthOutcome.Forbid,
AppSurfaceAuthReason.Forbidden);
ProblemDetails assertions verify the AppSurface extensions emitted by RequireSurfacePolicy(...):
using var json = JsonDocument.Parse(body);
AppSurfaceAuthTestAssert.HasProblemDetails(
json.RootElement,
AppSurfaceAuthOutcome.Challenge,
AppSurfaceAuthReason.Unauthenticated,
StatusCodes.Status401Unauthorized,
"OperatorsOnly");
Assertion failures throw AppSurfaceTestAuthAssertionException with diagnostic code ASTAUTH006.
Troubleshooting
| Problem | Cause | Fix | Code |
|---|---|---|---|
| Blank persona name | A persona was added without a stable name. | Use a non-empty ordinal name such as operator. |
ASTAUTH001 |
| Duplicate persona | Two personas use the same ordinal name. | Rename one persona or remove the duplicate. | ASTAUTH002 |
| Unknown persona | CreateAppSurfaceClient(...) or request-level persona selection used a persona that is not registered. |
Add the persona in WithAppSurfaceTestAuth(...) or correct the test value. |
ASTAUTH003 |
| Production environment blocked | Test auth started outside Development, Test, or Testing. |
Run the test host in a test environment, or set AllowProductionEnvironmentForTestHost = true only for isolated production-like integration tests. |
ASTAUTH004 |
| Blank scheme name | SchemeName was set to an empty value. |
Leave the default AppSurface.Test or set a non-empty name. |
ASTAUTH005 |
| Assertion failed | Expected auth contract does not match the actual AppSurface result or ProblemDetails payload. | Fix the host auth setup or update the expected contract. | ASTAUTH006 |
| Blank subject claim type | SubjectClaimType was set to an empty value. |
Set a non-empty claim type or leave it null to preserve host mapping. | ASTAUTH007 |
What The Package Includes
AddAppSurfaceTestAuth(...)WithAppSurfaceTestAuth(...)CreateAppSurfaceClient(...)WithAppSurfaceTestPersona(...)AppSurfaceTestAuthOptionsAppSurfaceTestPersonaAppSurfaceTestAuthSchemeModeAppSurfaceTestAuthDiagnosticCodesAppSurfaceAuthTestAssertAppSurfaceTestAuthAssertionException- deterministic test personas
- production-environment guard
- framework-neutral AppSurface auth result and ProblemDetails assertions
What The Package Does Not Include
- Production authentication
- Cookies, JWT/OIDC, OAuth, or ASP.NET Identity setup
- Identity-provider hosting
- Authorization policy ownership
- Middleware replacement
- User stores, provisioning, or app-user mapping
- Browser login flows
- Dev Auth runtime personas
- Session freshness simulation
- Policy bypasses
Auth Package Ladder
Use ForgeTrust.AppSurface.Auth.Testing for integration tests that need deterministic personas and canonical AppSurface assertions.
Use ForgeTrust.AppSurface.Auth.AspNetCore in production ASP.NET Core hosts that already own authentication and authorization but need AppSurface-shaped auth results.
Use ForgeTrust.AppSurface.Auth.AspNetCore.Oidc when a web host has chosen an OIDC provider and wants AppSurface-named cookie/OIDC scheme conventions.
Use Dev Auth for local runtime persona switching during manual development. Dev Auth is intentionally different from this package: it is a local runtime convenience, while Auth.Testing is a deterministic test harness.
Use raw ASP.NET Core authentication and authorization when the app needs production schemes, policies, middleware behavior, challenge/forbid execution, redirects, or provider integration.
Pitfalls
- Do not register Auth.Testing in production app startup. It is for test hosts.
- Do not rely on the internal persona transport header. Use
CreateAppSurfaceClient(...)orWithAppSurfaceTestPersona(...). - Do not use
DefaultSchemewhen the test must prove an existing host default remains untouched. UseNamedSchemeorNoDefault. - Do not use personas to model stale sessions. Stale or unknown session behavior belongs to real session seams; this package only helps assert the existing
StaleOrUnknownSessionresult and ProblemDetails mapping.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- CliWrap (>= 3.10.1)
- ForgeTrust.AppSurface.Auth (>= 0.2.0-preview.2)
- ForgeTrust.AppSurface.Auth.AspNetCore (>= 0.2.0-preview.2)
- Microsoft.AspNetCore.Mvc.Testing (>= 10.0.2)
- Microsoft.Extensions.DependencyModel (>= 10.0.2)
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 |
|---|---|---|
| 0.2.0-preview.2 | 0 | 7/3/2026 |
| 0.2.0-preview.1 | 226 | 6/28/2026 |