Centeva.PrincipalProvider
2.0.0
Prefix Reserved
dotnet add package Centeva.PrincipalProvider --version 2.0.0
NuGet\Install-Package Centeva.PrincipalProvider -Version 2.0.0
<PackageReference Include="Centeva.PrincipalProvider" Version="2.0.0" />
<PackageVersion Include="Centeva.PrincipalProvider" Version="2.0.0" />
<PackageReference Include="Centeva.PrincipalProvider" />
paket add Centeva.PrincipalProvider --version 2.0.0
#r "nuget: Centeva.PrincipalProvider, 2.0.0"
#:package Centeva.PrincipalProvider@2.0.0
#addin nuget:?package=Centeva.PrincipalProvider&version=2.0.0
#tool nuget:?package=Centeva.PrincipalProvider&version=2.0.0
Centeva.PrincipalProvider
Provides abstractions and implementations for user principal management in .NET applications, including support for web and background task scenarios.
Upgrading from v1? See the 2.0 Upgrade Guide.
Installation
Add the NuGet package to your project:
dotnet add package Centeva.PrincipalProvider
Or via the NuGet Package Manager in Visual Studio:
- Open the NuGet Package Manager
- Search for
Centeva.PrincipalProvider - Click Install
Usage
1. Register Services
services.AddHttpContextAccessor();
services.AddSingleton<TaskRunnerPrincipalProvider>(sp =>
new TaskRunnerPrincipalProvider(
authorizationKey: "your-authorization-key",
authorizedUserName: "TaskRunnerUser", // display name for background tasks
email: "jobs@example.com" // optional, see Background Tasks below
)
);
services.AddScoped<IPrincipalProvider, WebPrincipalProvider>();
AddHttpContextAccessor() is required — WebPrincipalProvider cannot be constructed without it.
To inject the principal directly, register it as IPrincipal (the type UserPrincipal returns):
services.AddScoped(sp => sp.GetRequiredService<IPrincipalProvider>().UserPrincipal);
2. Accessing the Principal
Inject IPrincipalProvider where needed:
public class MyService(IPrincipalProvider principalProvider)
{
public void DoSomething()
{
var email = principalProvider.Email;
var principal = principalProvider.UserPrincipal;
}
}
Claims this interface does not surface — the token's subject among them — are reachable through
UserPrincipal. See ADR 0001 for why the subject is
deliberately not exposed as a property.
3. Background Tasks
For background jobs, use TaskRunnerPrincipalProvider:
var provider = new TaskRunnerPrincipalProvider("your-authorization-key", "TaskRunnerUser");
var principal = provider.UserPrincipal;
Values passed to the constructor are exposed both as properties and as claims on
UserPrincipal, so application code reaches the same answer either way.
They do not affect ASP.NET Core authorization policies, which evaluate HttpContext.User.
A background job is not an HTTP request, so no policy runs against this principal.
API
IPrincipalProvider
Interface for principal providers.
| Member | Type | Description |
|---|---|---|
AuthorizationKey |
string |
The authorization key for the user context. Used to detect the TaskRunner bypass. |
AuthorizedUserName |
string |
Display name used as the identity of UserPrincipal. A label, not an identifier. |
AuthorizedUserId |
string |
Obsolete. The 1.x name for AuthorizedUserName, kept as an alias so existing source compiles unchanged. Same value under both names; will be removed in 3.0. |
UserPrincipal |
IPrincipal |
The full security principal for the user. |
Email |
string? |
The user's email address. Reads ClaimTypes.Email or raw email. null for app-only tokens. |
ApplicationId |
string? |
The calling application identifier. Reads azp or appid. null for delegated-user tokens. |
Each claim is read under more than one name because the name is not fixed by the token:
Email— inbound claim mapping is a host-level setting. With mapping on (the framework default)emailarrives rewritten to itsClaimTypes.*URI; with it off the raw name survives. Both are accepted so the property does not depend on that setting.ApplicationId—azpandappidare the same claim under two token versions. Entra ID emitsazpon v2.0 tokens andappidon v1.0; Keycloak emitsazp. Accepting both keeps a tenant's token version out of application code.
WebPrincipalProvider
Uses IHttpContextAccessor to provide the current web user's principal and claims.
Email and ApplicationId are derived from the same ClaimsPrincipal as UserPrincipal, so
no extra extraction is needed in application code.
When AuthorizationKey matches the injected TaskRunnerPrincipalProvider's key, all three
members switch to the task runner identity.
TaskRunnerPrincipalProvider
Provides a fixed principal for background tasks. Constructor parameters:
| Parameter | Required | Description |
|---|---|---|
authorizationKey |
✓ | Key that activates the TaskRunner bypass in WebPrincipalProvider. |
authorizedUserName |
Display name for the background identity. Defaults to "TaskRunnerUser". |
|
email |
Email address. Supply when application code run by the job resolves the current user by email. | |
applicationId |
Application identifier (azp / appid). Supply for app-only token scenarios. |
UserPrincipal is a ClaimsPrincipal whose identity has AuthenticationType of "TaskRunner"
(the TaskRunnerPrincipalProvider.AuthenticationType constant), so application code can tell a
background identity from a signed-in one. It carries ClaimTypes.Name, plus ClaimTypes.Email
and azp for whichever values were supplied.
Using with Centeva.Oidc
Centeva.PrincipalProvider is designed to work alongside the
Centeva.Oidc package suite, which registers
the API, Dashboard and Scalar authorization policies. Both packages read the same claims
under the same set of alternative names, so a request that Centeva.Oidc authorizes always
resolves to a non-null principal value here.
| Claim | Centeva.Oidc uses it to |
Centeva.PrincipalProvider exposes it as |
|---|---|---|
email / ClaimTypes.Email |
Require it on delegated tokens; gate the Hangfire dashboard | Email |
azp / appid |
Authorize app-only (client-credentials) callers | ApplicationId |
sub / NameIdentifier |
Require it on delegated tokens | Not exposed — read from UserPrincipal |
Example wiring in Program.cs:
builder.Services.AddOidcAuth()
.WithOptions(options =>
{
options.Authority = "https://auth.example.com/realms/my-realm";
options.Audience = "my-api";
options.ClientId = "my-client";
options.DashboardAccessPredicate = email => email.EndsWith("@example.com");
});
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<TaskRunnerPrincipalProvider>(sp =>
new TaskRunnerPrincipalProvider("your-authorization-key", email: "jobs@example.com"));
builder.Services.AddScoped<IPrincipalProvider, WebPrincipalProvider>();
Target Frameworks
- .NET 8, 9, 10
- C# 12
License
Distributed under the MIT License.
| 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
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Centeva.PrincipalProvider:
| Package | Downloads |
|---|---|
|
Centeva.Hangfire.HangfireScheduler
Provides abstractions and base implementations for configuring, scheduling, and managing Hangfire background tasks in .NET 8+ applications. Includes support for dependency injection and customizable task registration for both web and background processing scenarios. |
GitHub repositories
This package is not used by any popular GitHub repositories.