Class IdentityDirectoryServiceCollectionExtensions
- Namespace
- Microsoft.Extensions.DependencyInjection
- Assembly
- Stratara.Identity.EntityFrameworkCore.dll
DI extensions that register the Stratara identity-directory plane: the EF-backed tenant membership store, the membership-backed authorization provider, and the membership-backed cross-tenant authorizer.
public static class IdentityDirectoryServiceCollectionExtensions
- Inheritance
-
IdentityDirectoryServiceCollectionExtensions
- Inherited Members
Methods
AddApiKeyStoreFromContextFactory<TContext>(IServiceCollection)
Register the EF Core IApiKeyStore against TContext, taking
a fresh context for each operation from the registered context factory.
public static IServiceCollection AddApiKeyStoreFromContextFactory<TContext>(this IServiceCollection services) where TContext : DbContext
Parameters
servicesIServiceCollectionThe service collection to mutate.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Type Parameters
TContextThe DbContext hosting the directory tables.
Examples
Needs AddDbContextFactory<TContext>(); one context per operation:
services.AddDbContextFactory<DirectoryDbContext>();
services.AddApiKeyStoreFromContextFactory<DirectoryDbContext>();
Remarks
Each operation creates its own context from the registered IDbContextFactory<TContext> and disposes it afterwards, so directory operations issued concurrently within one scope do not contend and a store's commit reaches only its own rows. In exchange, a store write does not take part in a transaction the consumer opened on their own scoped context.
Requires AddDbContextFactory<TContext>(); a missing registration fails at first
resolution rather than silently. Keep the factory's options aligned with the scoped
registration — interceptors, query filters and conventions are configured per registration,
not per context type.
Calling this together with AddApiKeyStore<TContext>(IServiceCollection) leaves whichever ran first in place; they do not compose.
AddApiKeyStore<TContext>(IServiceCollection)
Register the EF Core IApiKeyStore against
TContext — issuance (raw key shown once, hash stored), idempotent
import of a caller-supplied key for bootstrap scenarios, fail-closed validation, revocation,
and per-tenant/per-user erasure sweeps. Machine keys are materialized as memberships of
their tenant, so they flow through the same role/permission plane as human actors.
public static IServiceCollection AddApiKeyStore<TContext>(this IServiceCollection services) where TContext : DbContext
Parameters
servicesIServiceCollectionThe service collection to mutate.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Type Parameters
TContextThe DbContext hosting the directory tables.
Examples
services.AddApiKeyStore<DirectoryDbContext>();
Remarks
The store shares the context registered for the request, so directory operations issued concurrently within one scope fail on whichever arrives second — a database context serves one operation at a time — and the store's own commit also commits whatever else the consumer has left unsaved on that context. Register the store with AddApiKeyStoreFromContextFactory<TContext>(IServiceCollection) instead to give each operation its own context.
Calling both registrations leaves whichever ran first in place; they do not compose.
AddCatalogPermissionResolver(IServiceCollection)
Register CatalogPermissionResolver as the IPermissionResolver — permissions derive from tenant-scoped membership roles mapped through the catalog's role grants. Use the generic overload (AddCatalogPermissionResolver<TUser>(IServiceCollection)) when global ASP.NET Identity roles should also grant permissions.
public static IServiceCollection AddCatalogPermissionResolver(this IServiceCollection services)
Parameters
servicesIServiceCollectionThe service collection to mutate.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Examples
Resolves a principal's permissions by running its membership roles through the catalog:
services.AddPermissionCatalog(c => c.Add("sims.read"));
services.AddCatalogPermissionResolver();
AddCatalogPermissionResolver<TUser>(IServiceCollection)
Register CatalogPermissionResolver<TUser> as the
IPermissionResolver — permissions derive from tenant-scoped membership roles
and global ASP.NET Identity roles, mapped through the catalog's role grants.
Requires the host's Identity registration (UserManager<TUser> resolvable).
public static IServiceCollection AddCatalogPermissionResolver<TUser>(this IServiceCollection services) where TUser : class
Parameters
servicesIServiceCollectionThe service collection to mutate.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Type Parameters
TUserThe host's ASP.NET Identity user entity.
Examples
The generic overload also considers the user's global ASP.NET Core Identity roles:
services.AddCatalogPermissionResolver<ApplicationUser>();
AddMembershipAuthorization(IServiceCollection)
Register MembershipAuthorizationProvider as the IAuthorizationProvider — role checks pass on tenant-scoped membership roles only. Use the generic overload (AddMembershipAuthorization<TUser>(IServiceCollection)) when the host also gates on global ASP.NET Identity roles.
public static IServiceCollection AddMembershipAuthorization(this IServiceCollection services)
Parameters
servicesIServiceCollectionThe service collection to mutate.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Examples
Resolves roles from tenant-scoped membership. Pair it with the authorizing mediator, which is what enforces the attributes:
services.AddMembershipAuthorization();
services.AddAuthorizingMediator<MembershipAuthorizationProvider>();
Remarks
Hosts that dispatch through the authorizing mediator pass the provider type there instead
(AddAuthorizingMediator<MembershipAuthorizationProvider>()); this registration
serves components that resolve IAuthorizationProvider directly, such as the
authorizing outbox dispatcher.
AddMembershipAuthorization<TUser>(IServiceCollection)
Register MembershipAuthorizationProvider<TUser> as the
IAuthorizationProvider — role checks pass on tenant-scoped membership roles
or global ASP.NET Identity roles (platform roles). Requires the host's Identity
registration (UserManager<TUser> resolvable).
public static IServiceCollection AddMembershipAuthorization<TUser>(this IServiceCollection services) where TUser : class
Parameters
servicesIServiceCollectionThe service collection to mutate.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Type Parameters
TUserThe host's ASP.NET Identity user entity.
Examples
The generic overload adds the user's global ASP.NET Core Identity roles to the membership roles:
services.AddMembershipAuthorization<ApplicationUser>();
AddMembershipCrossTenantAuthorizer(IServiceCollection, Action<MembershipCrossTenantAuthorizerOptions>?)
Register MembershipCrossTenantAuthorizer as the ICrossTenantAuthorizer consulted by strict tenant isolation: cross-tenant operations are allowed for actors with an active membership in the data-owner tenant or with one of the configured cross-tenant roles.
public static IServiceCollection AddMembershipCrossTenantAuthorizer(this IServiceCollection services, Action<MembershipCrossTenantAuthorizerOptions>? configure = null)
Parameters
servicesIServiceCollectionThe service collection to mutate.
configureAction<MembershipCrossTenantAuthorizerOptions>Optional callback to configure the permitted cross-tenant roles.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Examples
Strict isolation where only platform administrators may cross tenants without membership:
builder.Services
.AddStrataraTenantIsolation(o => o.Mode = TenantIsolationMode.Strict)
.AddMembershipCrossTenantAuthorizer(o => o.CrossTenantRoles.Add("PlatformAdmin"));
AddPermissionCatalog(IServiceCollection, Action<PermissionCatalog>)
Build and register the application's PermissionCatalog (singleton) — the declared permission vocabulary plus its role→permission grants, consumed by the catalog permission resolvers and the HTTP permission policies.
public static IServiceCollection AddPermissionCatalog(this IServiceCollection services, Action<PermissionCatalog> configure)
Parameters
servicesIServiceCollectionThe service collection to mutate.
configureAction<PermissionCatalog>Callback that declares permissions and role grants.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Examples
The catalog is the vocabulary: granting a permission it does not declare throws at start-up rather than silently granting nothing:
services.AddPermissionCatalog(c =>
{
c.Add("sims.read", "sims.write");
c.GrantToRole("TenantAdmin", "sims.read", "sims.write");
});
AddSettingCatalog(IServiceCollection, Action<SettingCatalog>)
Build and register the application's SettingCatalog (singleton) — the declared setting vocabulary with defaults and flags, consumed by the setting provider and the encrypting store decorator.
public static IServiceCollection AddSettingCatalog(this IServiceCollection services, Action<SettingCatalog> configure)
Parameters
servicesIServiceCollectionThe service collection to mutate.
configureAction<SettingCatalog>Callback that declares the settings.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Examples
Declares each setting with its default, whether it inherits down the scope chain, and whether it is stored encrypted:
services.AddSettingCatalog(c => c.Add(
new SettingDefinition("ui.theme", DefaultValue: "light"),
new SettingDefinition("billing.vatId", IsInherited: false)));
AddSettingStoreFromContextFactory<TContext>(IServiceCollection)
Register the EF Core ISettingStore against TContext and the
scope-fallback ISettingProvider read facade, taking a fresh context for each
operation from the registered context factory. The encrypting decorator is applied exactly as
it is for the shared registration.
public static IServiceCollection AddSettingStoreFromContextFactory<TContext>(this IServiceCollection services) where TContext : DbContext
Parameters
servicesIServiceCollectionThe service collection to mutate.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Type Parameters
TContextThe DbContext hosting the directory tables.
Examples
Needs AddDbContextFactory<TContext>(); one context per operation:
services.AddDbContextFactory<DirectoryDbContext>();
services.AddSettingStoreFromContextFactory<DirectoryDbContext>();
Remarks
Each operation creates its own context from the registered IDbContextFactory<TContext> and disposes it afterwards, so directory operations issued concurrently within one scope do not contend and a store's commit reaches only its own rows. In exchange, a store write does not take part in a transaction the consumer opened on their own scoped context.
Requires AddDbContextFactory<TContext>(); a missing registration fails at first
resolution rather than silently. Keep the factory's options aligned with the scoped
registration — interceptors, query filters and conventions are configured per registration,
not per context type.
Calling this together with AddSettingStore<TContext>(IServiceCollection) leaves whichever ran first in place; they do not compose.
AddSettingStore<TContext>(IServiceCollection)
Register the EF Core ISettingStore against
TContext, plus the scope-fallback
ISettingProvider read facade. When the
registered SettingCatalog declares encrypted
settings, the store is wrapped in a transparent AES-GCM decorator (requires the security
plane's ISecureBlobEncryptor registration —
missing it fails at first resolution, not silently).
public static IServiceCollection AddSettingStore<TContext>(this IServiceCollection services) where TContext : DbContext
Parameters
servicesIServiceCollectionThe service collection to mutate.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Type Parameters
TContextThe DbContext hosting the directory tables.
Examples
Registers the store and the provider facade that walks the fallback chain. Declare the vocabulary first — a setting the catalog does not know has no default to fall back to:
services.AddSettingCatalog(c => c.Add(new SettingDefinition("ui.theme", DefaultValue: "light")));
services.AddSettingStore<DirectoryDbContext>();
Remarks
The store shares the context registered for the request, so directory operations issued concurrently within one scope fail on whichever arrives second — a database context serves one operation at a time — and the store's own commit also commits whatever else the consumer has left unsaved on that context. Register the store with AddSettingStoreFromContextFactory<TContext>(IServiceCollection) instead to give each operation its own context.
Calling both registrations leaves whichever ran first in place; they do not compose.
AddTenantMembershipStoreFromContextFactory<TContext>(IServiceCollection)
Register the EF Core ITenantMembershipStore against TContext,
taking a fresh context for each operation from the registered context factory.
public static IServiceCollection AddTenantMembershipStoreFromContextFactory<TContext>(this IServiceCollection services) where TContext : DbContext
Parameters
servicesIServiceCollectionThe service collection to mutate.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Type Parameters
TContextThe DbContext hosting the directory tables.
Examples
Needs AddDbContextFactory<TContext>(). Each operation takes a fresh context, so
directory work issued concurrently in one scope no longer collides — in exchange, a store write
does not join a transaction opened on your own scoped context:
services.AddDbContextFactory<DirectoryDbContext>();
services.AddTenantMembershipStoreFromContextFactory<DirectoryDbContext>();
Remarks
Each operation creates its own context from the registered IDbContextFactory<TContext> and disposes it afterwards, so directory operations issued concurrently within one scope do not contend and a store's commit reaches only its own rows. In exchange, a store write does not take part in a transaction the consumer opened on their own scoped context.
Requires AddDbContextFactory<TContext>(); a missing registration fails at first
resolution rather than silently. Keep the factory's options aligned with the scoped
registration — interceptors, query filters and conventions are configured per registration,
not per context type.
Calling this together with AddTenantMembershipStore<TContext>(IServiceCollection) leaves whichever ran first in place; they do not compose.
AddTenantMembershipStore<TContext>(IServiceCollection)
Register the EF Core ITenantMembershipStore against TContext.
The context's model must include the identity-directory tables — derive from
IdentityDirectoryDbContext<TContext> or call
ApplyIdentityDirectoryModel(ModelBuilder) in the
context's OnModelCreating. The context itself must already be registered
(for example via AddDbContext or a pooled factory).
public static IServiceCollection AddTenantMembershipStore<TContext>(this IServiceCollection services) where TContext : DbContext
Parameters
servicesIServiceCollectionThe service collection to mutate.
Returns
- IServiceCollection
The same service collection, to enable chaining.
Type Parameters
TContextThe DbContext hosting the directory tables.
Examples
TContext is any context whose model includes the directory tables — derive from
IdentityDirectoryDbContext<TContext> or call ApplyIdentityDirectoryModel() in
OnModelCreating. Every directory store in a request shares this one context:
services.AddTenantMembershipStore<DirectoryDbContext>();
Remarks
The store shares the context registered for the request, so directory operations issued concurrently within one scope fail on whichever arrives second — a database context serves one operation at a time — and the store's own commit also commits whatever else the consumer has left unsaved on that context. Register the store with AddTenantMembershipStoreFromContextFactory<TContext>(IServiceCollection) instead to give each operation its own context.
Calling both registrations leaves whichever ran first in place; they do not compose.