---
title: Service registration
summary: Services, options, and required consumer registrations that `SAIF.NetCore.AuthService` contributes to a consuming application.
status: draft
owner: Framework.NCore maintainers
last_reviewed: 2026-10-02
library: SAIF.NetCore.AuthService
reference_type: package
---

# Service registration

`SAIF.NetCore.AuthService` exposes eight `IServiceCollection`/`AuthenticationBuilder` extension methods on `AuthenticationServiceExtensions`, used by web/API hosting contexts, that register an outbound OAuth token client, one or more `IIdentityService` implementations, authentication schemes, and the declarative `[SecurityApiAuthorize]` authorization pipeline; none of these methods register the `JwtBearer` authentication handler itself, `ConfigureJwtBearerOptions`, or the `IEnvironmentClient`/`IHttpJsonClient`/`IHttpContextAccessor` dependencies the library's own types require — the consuming application must register those separately.

## Registration extension catalog

Extension methods a consuming application calls to register this library's services.

| Extension method | Hosting context | Parameters | Source |
| --- | --- | --- | --- |
| `AddAccessTokenClient(this IServiceCollection services)` | web \| API \| worker | None. | `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/Extensions/AuthenticationServiceExtensions.cs` |
| `AddTokenIdentityService(this IServiceCollection services)` | web \| API | None. Registers a single `IIdentityService` interface mapping to `TokenIdentityService`. | same |
| `AddWinIdentityService(this IServiceCollection services)` | web \| API | None. Registers a single `IIdentityService` interface mapping to `WinIdentityService`. | same |
| `AddIdentityAccessor(this IServiceCollection services)` | web \| API | None. Registers **both** `TokenIdentityService` and `WinIdentityService` as concrete self-bindings (not a single `IIdentityService` mapping), plus `MultiIdentityServiceAccessor`, for applications that must support both schemes at runtime. | same |
| `AddJwtAuthentication(this IServiceCollection services)` | web \| API | None. Sets the default authentication scheme to `JwtBearerDefaults.AuthenticationScheme`; does **not** call `.AddJwtBearer()`, so the actual JWT bearer handler is not registered by this call. | same |
| `AddIISAuthentication(this IServiceCollection services)` | web \| API (IIS/IIS Express hosted) | None. Sets the default authentication scheme to `IISServerDefaults.AuthenticationScheme`. | same |
| `AddDualAuthentication(this IServiceCollection services)` | web \| API | None. Registers a `"dual"` policy scheme as the default scheme/challenge scheme; `ForwardDefaultSelector` is assigned the then-current `AuthenticationSchemeSelector` delegate inside the `AddPolicyScheme` options-configuration callback, when the named policy-scheme options are configured, not directly during this extension's invocation. | same |
| `AddSecurityApiAuthorizeAttribute(this IServiceCollection services)` | web \| API | None. Registers the `[SecurityApiAuthorize]` declarative pipeline (`SecurityApiPolicy`, `SecurityApiHandler`). | same |

## Service registration catalog

| Service type | Implementation | Lifetime | Registered by | Condition | Source |
| --- | --- | --- | --- | --- | --- |
| `IAccessTokenClient` | `OktaTokenClient` | Singleton | `AddAccessTokenClient` | Always | `Extensions/AuthenticationServiceExtensions.cs` |
| `ISecurityClient` | `SecurityClient` | Singleton | `AddTokenIdentityService`, `AddWinIdentityService`, `AddIdentityAccessor` | Always (each of these three methods registers it) | `Extensions/AuthenticationServiceExtensions.cs` |
| `IIdentityService` | `TokenIdentityService` | Scoped | `AddTokenIdentityService` | Always | `Extensions/AuthenticationServiceExtensions.cs` |
| `IIdentityService` | `WinIdentityService` | Scoped | `AddWinIdentityService` | Always | `Extensions/AuthenticationServiceExtensions.cs` |
| `IIdentityServiceAccessor` | `IdentityServiceAccessor` | Transient | `AddTokenIdentityService`, `AddWinIdentityService` | Always (each registers it) | `Extensions/AuthenticationServiceExtensions.cs` |
| `WinIdentityService` (concrete self-binding) | `WinIdentityService` | Scoped | `AddIdentityAccessor` | Always | `Extensions/AuthenticationServiceExtensions.cs` |
| `TokenIdentityService` (concrete self-binding) | `TokenIdentityService` | Scoped | `AddIdentityAccessor` | Always | `Extensions/AuthenticationServiceExtensions.cs` |
| `IIdentityServiceAccessor` | `MultiIdentityServiceAccessor` | Transient | `AddIdentityAccessor` | Always | `Extensions/AuthenticationServiceExtensions.cs` |
| `IAuthorizationPolicyProvider` | `SecurityApiPolicy` | Transient | `AddSecurityApiAuthorizeAttribute` | Always | `Extensions/AuthenticationServiceExtensions.cs` |
| `IAuthorizationHandler` | `SecurityApiHandler` | Singleton | `AddSecurityApiAuthorizeAttribute` | Always | `Extensions/AuthenticationServiceExtensions.cs` |

`AddIdentityAccessor` registers `ISecurityClient`, both concrete identity-service types, and `MultiIdentityServiceAccessor` together; it is not equivalent to calling `AddTokenIdentityService`/`AddWinIdentityService`, which each map a single `IIdentityService` interface instead of registering both concrete types.

## Options configuration

| Options type | Named instance | Configured by | Configuration keys / services read | Source |
| --- | --- | --- | --- | --- |
| `JwtBearerOptions` | `JwtBearerDefaults.AuthenticationScheme` | `ConfigureJwtBearerOptions` (`IConfigureNamedOptions<JwtBearerOptions>`) — **not registered by any extension method in this library; the consumer must register it explicitly** (for example `services.ConfigureOptions<ConfigureJwtBearerOptions>()` or an equivalent DI registration) | `authority`/`oauth`, `audience`/`oauth`, `requirehttpsmetadata`/`oauth` (plus per-application overrides `authority.{ApplicationName}`/`audience.{ApplicationName}`), read via the injected `IEnvironmentClient` | `ConfigureJwtBearerOptions.cs` |

## Required-but-not-registered services

Services this library's types resolve that none of its registration methods add. The consuming application, or another library, must register them.

| Service type | Consumer | Expected source |
| --- | --- | --- |
| `IEnvironmentClient` | `SecurityClient`, `BaseIdentityService`/derivatives, `ConfigureJwtBearerOptions` | Host application (typically via `SAIF.NetCore.EnvironmentClient` or an equivalent `SAIF.NetCore.ServiceContracts` implementation) |
| `IHttpJsonClient` | `SecurityClient` | Host application (typically via `SAIF.NetCore.HttpClients` or an equivalent `SAIF.NetCore.ServiceContracts` implementation) |
| `IHttpContextAccessor` | `BaseIdentityService`/derivatives, `IdentityServiceAccessor`, `MultiIdentityServiceAccessor`, `OktaTokenClient` | Host application (`services.AddHttpContextAccessor()`) |
| JwtBearer authentication handler (`.AddJwtBearer()`) | Any consumer selecting the JWT scheme via `AddJwtAuthentication()`/`AddDualAuthentication()` | Host application — not registered by `AddJwtAuthentication()` or `AddDualAuthentication()` |
| `ConfigureJwtBearerOptions` registered as `IConfigureOptions<JwtBearerOptions>` (for example via `services.ConfigureOptions<ConfigureJwtBearerOptions>()`) | JwtBearer authentication handler | Host application — not registered by any extension method in this library |
| `IOptions<AuthorizationOptions>` | `SecurityApiPolicy` (constructs a `DefaultAuthorizationPolicyProvider` from it) | Host application — populated by the framework's own `services.AddAuthorization()` call, which `AddSecurityApiAuthorizeAttribute()` does not invoke; a consumer that registers `[SecurityApiAuthorize]` via `AddSecurityApiAuthorizeAttribute()` must also call `AddAuthorization()` so `IOptions<AuthorizationOptions>` resolves |

## Lifetime constraints

- `OktaTokenClient` (`IAccessTokenClient`) is Singleton but holds mutable token-cache state and settable credential properties without synchronization; see [Architecture](architecture.md) for the concurrency implications.
- `SecurityClient` (`ISecurityClient`) is always registered Singleton by every registration method that adds it, regardless of which identity-service registration method is used.
- `AddTokenIdentityService`/`AddWinIdentityService` register `IIdentityService` Scoped; `AddIdentityAccessor` registers both concrete identity-service types Scoped and `MultiIdentityServiceAccessor` Transient. Mixing a single-identity method with manual multi-accessor registration can leave one of the two concrete types unregistered, causing `MultiIdentityServiceAccessor` to resolve `null` for that scheme* (see [MultiIdentityServiceAccessor](api/SAIF.NetCore.Services.Authentication.Identity/MultiIdentityServiceAccessor.md)).
- `SecurityApiHandler` (`IAuthorizationHandler`) is Singleton and depends on `ISecurityClient`; `SecurityApiPolicy` (`IAuthorizationPolicyProvider`) is Transient.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [API reference](api/index.md)

Selecting the JWT scheme via `AddJwtAuthentication()` (or `AddDualAuthentication()`'s JwtBearer branch) does **not** automatically register the JwtBearer authentication handler or `ConfigureJwtBearerOptions`. A consumer must separately call `.AddJwtBearer()` on the returned `AuthenticationBuilder` (or an equivalent explicit registration) and register `ConfigureJwtBearerOptions` via `services.ConfigureOptions<ConfigureJwtBearerOptions>()` (or an equivalent `IConfigureOptions<JwtBearerOptions>` registration) for JWT authentication to function. `ConfigureJwtBearerOptions` implements `IConfigureNamedOptions<JwtBearerOptions>`, so the options factory invokes its named-configuration overload once it is registered this way, but implementing that interface does not itself register the setup with the DI container — registering only an `IConfigureNamedOptions<JwtBearerOptions>` service type leaves it absent from the options factory's `IConfigureOptions<JwtBearerOptions>` enumeration.

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts. Statements marked with `**` could not be confirmed; treat
> as unknown until verified.

## Sources
- `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/Extensions/AuthenticationServiceExtensions.cs`
- `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/ConfigureJwtBearerOptions.cs`
