PrimusSaaS.Identity.Broker
2.6.0
dotnet add package PrimusSaaS.Identity.Broker --version 2.6.0
NuGet\Install-Package PrimusSaaS.Identity.Broker -Version 2.6.0
<PackageReference Include="PrimusSaaS.Identity.Broker" Version="2.6.0" />
<PackageVersion Include="PrimusSaaS.Identity.Broker" Version="2.6.0" />
<PackageReference Include="PrimusSaaS.Identity.Broker" />
paket add PrimusSaaS.Identity.Broker --version 2.6.0
#r "nuget: PrimusSaaS.Identity.Broker, 2.6.0"
#:package PrimusSaaS.Identity.Broker@2.6.0
#addin nuget:?package=PrimusSaaS.Identity.Broker&version=2.6.0
#tool nuget:?package=PrimusSaaS.Identity.Broker&version=2.6.0
Primus SaaS Identity Broker (BFF)
Server-side authentication middleware for ASP.NET Core browser apps.
This package implements a Backend-for-Frontend pattern for applications that want secure cookie sessions instead of storing access tokens in the browser. It handles local login, OIDC and SAML sign-in, MFA, and session lifecycle on the server side.
Package boundary
- Browser login and secure cookie session management
- Local login plus external providers such as Azure AD, Auth0, Google, Okta, and SAML
- CSRF protection with the double-submit-cookie pattern
- JIT provisioning hooks through
WithUserCheck(...)andWithAutoProvision(...) - Optional session refresh and impersonation endpoints
This package is not:
- an API token validator for downstream services
- a hosted identity provider
- a frontend UI kit
If your APIs already receive JWTs and only need validation, use PrimusSaaS.Identity.Validator instead.
Start here
- Getting started (15 min): AUTH_INTEGRATION_GUIDE.md
- Full config & endpoint reference: IDENTITY_BROKER_GUIDE.md
- Architecture deep dive: IDENTITY_BROKER_HOW_IT_WORKS.md
- Edge cases & troubleshooting: IDENTITY_BROKER_EDGE_CASES.md
- Docs site: packages/docs/docs/identity-broker/
Quick Start
1. Install Package
dotnet add package PrimusSaaS.Identity.Broker
2. Configure Access
Tell the broker how to look up or provision your users.
// In Program.cs
builder.Services.AddPrimusAuthBroker(builder.Configuration, builder.Environment.IsDevelopment())
.WithUserCheck(async (email, sp) =>
{
var db = sp.GetRequiredService<MyDbContext>();
var user = await db.Users.FirstOrDefaultAsync(u => u.Email == email);
return user == null ? null : new PrimusAuthUser { Id = user.Id, Email = user.Email, Role = user.Role };
})
.WithAutoProvision(async (email, provider, principal, sp) =>
{
// JIT provisioning (optional)
var db = sp.GetRequiredService<MyDbContext>();
var user = new User { Email = email, CreatedAt = DateTime.UtcNow };
db.Users.Add(user);
await db.SaveChangesAsync();
return new PrimusAuthUser { Id = user.Id, Email = user.Email };
});
3. Implement Credential Validator (Required for Local Login)
Local login is handled by the broker at POST /api/auth/login. To enable it, implement
IPrimusAuthCredentialValidator and verify credentials against your data store.
public class MyCredentialValidator : IPrimusAuthCredentialValidator
{
private readonly MyDbContext _db;
private readonly IPasswordHasher _hasher;
public MyCredentialValidator(MyDbContext db, IPasswordHasher hasher)
{
_db = db;
_hasher = hasher;
}
public async Task<PrimusAuthUser?> ValidateCredentialsAsync(string email, string password, CancellationToken ct = default)
{
var user = await _db.Users.FirstOrDefaultAsync(u => u.Email == email, ct);
if (user == null || !_hasher.VerifyPassword(password, user.PasswordHash))
{
return null;
}
return new PrimusAuthUser { Id = user.Id, Email = user.Email, Role = user.Role };
}
}
4. Register Services (Program.cs)
builder.Services.AddScoped<IPrimusAuthCredentialValidator, MyCredentialValidator>(); // If using local login
builder.Services.AddPrimusAuthBroker(builder.Configuration, builder.Environment.IsDevelopment());
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.UsePrimusCsrfProtection();
app.MapPrimusAuthBroker();
If token encryption remains enabled, configure PrimusAuth:Security:TokenEncryptionKey before startup. For a local-only sample host, you can instead use:
builder.Services.AddPrimusAuthBroker(
builder.Configuration,
builder.Environment.IsDevelopment(),
options => options.Security.EncryptTokens = false);
Azure AD uses /api/auth/azure/callback by default (or {AuthBroker:BasePath}/azure/callback).
Override with AzureAd:CallbackPath if your app registration already uses /signin-oidc.
Note: POST /api/auth/login requires a CSRF token. Call a safe endpoint like
GET /api/auth/providers on app startup to receive the XSRF-TOKEN cookie,
then mirror it in the X-Primus-CSRF header for state-changing requests.
Production checklist
- HTTPS: Mandatory. Cookies are Secure and __Host- prefixed.
- Data Protection: For multi-server deployments, configure shared keys so all instances can decrypt the session cookie:
builder.Services.AddPrimusBrokerDataProtection("MyUniqueAppName", new DirectoryInfo(@"C:\Keys")); - Secrets: Set PrimusAuth:Security:TokenEncryptionKey via Environment Variables.
Security note
You may see an SCS0009 warning about the XSRF-TOKEN cookie missing the HttpOnly flag. That is intentional. The browser-side code must be able to read that value and mirror it into the X-Primus-CSRF header for the double-submit-cookie pattern to work.
Configuration reference
Redirects
You can control where users are sent after login or error.
"Auth": {
"PostLoginRedirect": "/",
"ErrorRedirect": "/login"
}
- PostLoginRedirect: Where to go after success.
- ErrorRedirect: Where to go after failure (e.g.
User is not provisioned). If not set, a simple HTML error page is shown. The error message is passed as a query string:?error=....
7. Impersonation
The broker includes an impersonation flow for support and administrative scenarios.
How to use:
- Ensure your Admin user has the claim
role: Admin. - POST
/api/auth/impersonatewith{"targetEmail": "customer@example.com"}. - You are now logged in as the customer. Your token includes
act: admin@me.comfor audit trails. - To exit, POST
/api/auth/revert(Logs you out).
Troubleshooting
Startup Diagnostics
In Development environment only, you can view the current configuration status at:
GET /api/auth/__auth/diagnostics
This endpoint will show:
- Which User Store is active.
- Which Providers are enabled.
- Warnings if critical configuration is missing.
Common Errors
- NullPrimusAuthUserStore is active: You forgot to register
IPrimusAuthUserStore. See Step 2 above. - 401/403 loop: Check
CookieSameSiteMode. If using HTTP (not HTTPS), ensure your browser allows cookies.
Related guides
- AUTH_INTEGRATION_GUIDE.md — 15-minute first login with Angular + React + curl
- IDENTITY_BROKER_GUIDE.md — Every config key and endpoint
- IDENTITY_BROKER_HOW_IT_WORKS.md — BFF architecture deep dive
- IDENTITY_BROKER_EDGE_CASES.md — Security edge cases and troubleshooting
- Identity overview — All 8 Identity packages at a glance
| 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 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 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
- Fido2 (>= 4.0.0)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 10.0.5)
- Microsoft.AspNetCore.Authentication.OpenIdConnect (>= 10.0.5)
- Microsoft.Bcl.Memory (>= 10.0.5)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.16.0)
- Sustainsys.Saml2.AspNetCore2 (>= 2.11.0)
- System.Drawing.Common (>= 10.0.5)
- System.IdentityModel.Tokens.Jwt (>= 8.16.0)
-
net8.0
- Fido2 (>= 4.0.0)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 8.0.15)
- Microsoft.AspNetCore.Authentication.OpenIdConnect (>= 8.0.15)
- Microsoft.Bcl.Memory (>= 10.0.5)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.16.0)
- Sustainsys.Saml2.AspNetCore2 (>= 2.11.0)
- System.Drawing.Common (>= 8.0.15)
- System.IdentityModel.Tokens.Jwt (>= 8.16.0)
-
net9.0
- Fido2 (>= 4.0.0)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 9.0.14)
- Microsoft.AspNetCore.Authentication.OpenIdConnect (>= 9.0.14)
- Microsoft.Bcl.Memory (>= 10.0.5)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.16.0)
- Sustainsys.Saml2.AspNetCore2 (>= 2.11.0)
- System.Drawing.Common (>= 9.0.5)
- System.IdentityModel.Tokens.Jwt (>= 8.16.0)
NuGet packages (6)
Showing the top 5 NuGet packages that depend on PrimusSaaS.Identity.Broker:
| Package | Downloads |
|---|---|
|
PrimusSaaS.Identity.Broker.Tokens
Optional token issuance add-on for PrimusSaaS.Identity.Broker. Adds broker-issued access tokens, refresh tokens, and token exchange endpoints without changing the broker's default cookie-based behavior. |
|
|
PrimusSaaS.Memberships.InMemory
In-memory stores and bridge adapters for PrimusSaaS.Memberships development and test scenarios. |
|
|
PrimusSaaS.Identity.Broker.EntityFrameworkCore
Entity Framework Core user store for PrimusSaaS.Identity.Broker. Provides a generic base class for persisting broker user state using any EF Core-compatible database. |
|
|
PrimusSaaS.Memberships.Broker
Optional bridge that revokes Broker sessions and refresh tokens from Memberships lifecycle events. |
|
|
PrimusSaaS.Memberships.EFCore
Entity Framework Core integration for PrimusSaaS.Memberships. |
GitHub repositories
This package is not used by any popular GitHub repositories.
v2.5.1: Dedicated M2M app credentials — PrimusM2MOptions gains ClientId/ClientSecret; token service prefers them over broker credentials with fallback. | v2.5.0: M2M support — IPrimusM2MTokenService (outbound client credentials) + AddPrimusM2MValidation (inbound JwtBearer). | v2.4.0: Domain Allowlist, Webhooks, Bot Protection. | v2.3.0: TOTP MFA + token refresh. | v2.2.0: SAML 2.0.