Configuration reference
Every public options type of the published packages, every setting each one holds, and the value it has when nothing sets it. The page is generated from the compiled code: names, types and defaults are read from the assemblies by reflection — each default from a freshly constructed instance — and the descriptions are the XML documentation the build writes beside them. A test regenerates it on every build and fails when it differs from this file, so it describes the release it ships with.
How to read it:
- Property is the C# path from the options type you are handed in code, for example
AddIdentityServer(options => options.Authentication.CookieLifetime = …). - Configuration key is where the configuration binder reads the same setting. These packages bind no
configuration themselves: bind the section you choose, as the
getting started sample binds
IdentityServer. Keys are shown under a section named for the options type. Code only marks a setting the binder cannot read from strings — a certificate, a delegate, a service. - Default is the value a new instance holds. Times are
d.hh:mm:ss, as configuration writes them. A collection lists what it starts with.
Options types
- IdentityServerOptions —
Fdyay.IdentityServer.Core- EndpointsOptions
- DiscoveryOptions
- KeyManagementOptions
- SigningAlgorithmOptions
- UserInteractionOptions
- PushedAuthorizationOptions
- CorsOptions
- DeviceFlowOptions
- CibaOptions
- BackChannelLogoutOptions
- MutualTlsOptions
- EventsOptions
- DPoPOptions
- InputLengthRestrictions
- CspOptions
- ValidationOptions
- PersistentGrantOptions
- AuthenticationOptions
- DynamicProviderOptions —
Fdyay.IdentityServer.AspNetCore - LocalApiAuthenticationOptions —
Fdyay.IdentityServer.AspNetCore - SamlAuthenticationOptions —
Fdyay.IdentityServer.Saml - SamlOptions —
Fdyay.IdentityServer.Saml - SamlSpOptions —
Fdyay.IdentityServer.Saml - DapperStoreOptions —
Fdyay.IdentityServer.Dapper - ClientCredentialsClient —
Fdyay.AccessTokenManagement
IdentityServerOptions
Fdyay.IdentityServer.Configuration.IdentityServerOptions in Fdyay.IdentityServer.Core · configured with AddIdentityServer, AddIdentityServerCore · configuration key IdentityServer
Top-level configuration for the identity server.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.IssuerUri |
IdentityServer:IssuerUri |
string? |
null |
The issuer name (URI). If null, it is inferred from the request origin. |
IdentityServerOptions.LowerCaseIssuerUri |
IdentityServer:LowerCaseIssuerUri |
bool |
true |
Whether the lowercase issuer name is emitted. Defaults to true. |
IdentityServerOptions.Endpoints |
IdentityServer:Endpoints |
EndpointsOptions |
see EndpointsOptions | Endpoint enablement flags. |
IdentityServerOptions.Discovery |
IdentityServer:Discovery |
DiscoveryOptions |
see DiscoveryOptions | Discovery document options. |
IdentityServerOptions.KeyManagement |
IdentityServer:KeyManagement |
KeyManagementOptions |
see KeyManagementOptions | Key management options. |
IdentityServerOptions.UserInteraction |
IdentityServer:UserInteraction |
UserInteractionOptions |
see UserInteractionOptions | User interaction (login/consent) options. |
IdentityServerOptions.PushedAuthorization |
IdentityServer:PushedAuthorization |
PushedAuthorizationOptions |
see PushedAuthorizationOptions | Pushed authorization request behaviour (RFC 9126). |
IdentityServerOptions.Cors |
IdentityServer:Cors |
CorsOptions |
see CorsOptions | CORS settings for the protocol endpoints. |
IdentityServerOptions.DeviceFlow |
IdentityServer:DeviceFlow |
DeviceFlowOptions |
see DeviceFlowOptions | Device authorization grant behaviour (RFC 8628). |
IdentityServerOptions.Ciba |
IdentityServer:Ciba |
CibaOptions |
see CibaOptions | Back-channel authentication behaviour (OpenID Connect CIBA Core 1.0). |
IdentityServerOptions.BackChannelLogout |
IdentityServer:BackChannelLogout |
BackChannelLogoutOptions |
see BackChannelLogoutOptions | Back-channel logout notification behaviour (OpenID Connect Back-Channel Logout 1.0). |
IdentityServerOptions.MutualTls |
IdentityServer:MutualTls |
MutualTlsOptions |
see MutualTlsOptions | Mutual-TLS client authentication and certificate-bound tokens (RFC 8705). |
IdentityServerOptions.Events |
IdentityServer:Events |
EventsOptions |
see EventsOptions | Which kinds of event reach the sink. All off by default. |
IdentityServerOptions.DPoP |
IdentityServer:DPoP |
DPoPOptions |
see DPoPOptions | Options for DPoP (RFC 9449). |
IdentityServerOptions.InputLengths |
IdentityServer:InputLengths |
InputLengthRestrictions |
see InputLengthRestrictions | Bounds on the length of what a caller may send. |
IdentityServerOptions.Csp |
IdentityServer:Csp |
CspOptions |
see CspOptions | Content-Security-Policy for the pages and iframes this server serves. |
IdentityServerOptions.Validation |
IdentityServer:Validation |
ValidationOptions |
see ValidationOptions | Checks this server applies to values it has already accepted from a registration. |
IdentityServerOptions.PersistentGrants |
IdentityServer:PersistentGrants |
PersistentGrantOptions |
see PersistentGrantOptions | What this server does with the grants it persists. |
IdentityServerOptions.Authentication |
IdentityServer:Authentication |
AuthenticationOptions |
see AuthenticationOptions | The cookies this server writes itself, rather than through a framework handler. |
IdentityServerOptions.EmitStaticAudienceClaim |
IdentityServer:EmitStaticAudienceClaim |
bool |
false |
Whether every access token carries a static aud of {issuer}/resources in addition to the audiences of the API resources it was issued for. Off by default: a static audience every token carries is one every resource server has to be told to ignore.Backwards compatibility only, for deployments whose APIs were built against an older IdentityServer that emitted this audience unconditionally and validate it. It widens the audience of every token, so leave it off unless a resource server actually requires it. |
IdentityServerOptions.EmitIssuerIdentificationResponseParameter |
IdentityServer:EmitIssuerIdentificationResponseParameter |
bool |
true |
Whether an authorization response carries the iss parameter (RFC 9207). Defaults to true.The mix-up defence: a client that talks to more than one authorization server cannot otherwise tell which one a redirect came back from, because the response carries a code and a state and nothing that names its author. On by default, which is a deviation worth being deliberate about — RFC 9207 §2 says an authorization server should send it, and OAuth 2.0 requires a client to ignore response parameters it does not recognise, so emitting it cannot break a client that is not looking for it. Off is for a host that has found the client this does break, and turning it off also stops discovery advertising it: a client told the parameter is there and then not sent it fails the check that was the point of telling it. |
IdentityServerOptions.AccessTokenJwtType |
IdentityServer:AccessTokenJwtType |
string |
"at+jwt" |
The value written to the typ header of JWT access tokens. Defaults to at+jwt, per RFC 9068.Identity tokens are unaffected and always use JWT. Change this only for a resource server that rejects the RFC 9068 media type; some older stacks expect the bare JWT here. |
IdentityServerOptions.LogoutTokenJwtType |
IdentityServer:LogoutTokenJwtType |
string |
"logout+jwt" |
The value written to the typ header of back-channel logout tokens. Defaults to logout+jwt, per OpenID Connect Back-Channel Logout 1.0 §2.4. Duende's.Change this only for a relying party that rejects the explicit type. Empty writes the token handler's JWT, where Duende's writes no typ at all. A relying party following the specification may refuse a logout token typed anything else, so the default is the one to keep. |
IdentityServerOptions.EmitScopesAsSpaceDelimitedStringInJwt |
IdentityServer:EmitScopesAsSpaceDelimitedStringInJwt |
bool |
true |
Whether a JWT access token carries scope as one space-delimited string. Defaults to true.RFC 9068 §2.2.3 says the claim on an at+jwt access token is "a JSON string containing a space-separated list", and IdentityServerOptions.AccessTokenJwtType declares that media type by default — so this is what the token already claims to be doing.The alternative is not "an array": it is an array or a string depending on how many scopes the client asked for, because the payload builder collapses a single-valued claim to a scalar. A resource server written against a one-scope token reads a string and breaks the day a second scope is added to the client. Off is for a deployment whose resource servers were built against that array and have not been changed yet; it is not a shape this server recommends. Identity tokens are unaffected: scope is not an identity-token claim. |
IdentityServerOptions.ValidateTenantOnAuthorization |
IdentityServer:ValidateTenantOnAuthorization |
bool |
false |
Whether a session whose tenant claim differs from the request's tenant: hint is sent back to sign in. Defaults to false.Duende's name, default and rule, measured from its ProcessLoginAsync. |
IdentityServerOptions.TokenRequestDefaultScopesFromResourceStore |
IdentityServer:TokenRequestDefaultScopesFromResourceStore |
bool |
false |
Whether a client_credentials or extension grant token request that names no scope asks for the client's allowed scopes the resource store has, as Duende 8.0.1's does, and is refused when it would be granted none. Defaults to false: the client's allowed scopes as registered, as before.Duende's TokenRequestValidator.ValidateRequestedScopesAndResourcesAsync, measured. With it, a request naming no scope from a client with no allowed scopes is invalid_scope; client_credentials asks for the API scopes the store has among them (FindApiScopesByNameAsync), so an identity scope such as openid, or a name the store does not have, is left out rather than refused; an extension grant asks for the identity resources and API scopes the store has among them, and offline_access when the client allows offline access, so it gets a refresh token. And a request of either grant granted no scope at all is invalid_scope, as Duende's ResourceValidationResult.Succeeded requires one — a request naming its scopes is otherwise validated as before. Off by default because each changes what an existing client receives: a refusal becomes a token, a token gains a refresh token, or a token becomes a refusal. |
IdentityServerOptions.JwtValidationClockSkew |
IdentityServer:JwtValidationClockSkew |
TimeSpan |
00:00:00 |
How far past its exp a JWT access token this server issued is still accepted. Defaults to TimeSpan.Zero.Zero, and the reason is what clock skew is for. A tolerance exists so that two clocks that disagree do not reject each other — but the token being validated here was minted by this server, and read by this server at UserInfo, at introspection and at a local API. There is one clock, so there is nothing to tolerate, and every second of tolerance is a second in which expires_in did not mean what the token response said it meant.This is a change of behaviour rather than a new knob: nothing set ClockSkew on the validation parameters, so the value in force was IdentityModel's default of five minutes — a token was accepted for five minutes past the expiry this server had published for it, and no setting anywhere said so.The two places this server validates a JWT minted by somebody else — a client's request object and a client's authentication assertion — deliberately do not read this. There the two clocks are real and a tolerance is what keeps a client with a drifting clock working. |
IdentityServerOptions.SupportedRequestObjectSigningAlgorithms |
IdentityServer:SupportedRequestObjectSigningAlgorithms |
ICollection<string> |
[ "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" ] |
The signing algorithms a request object (RFC 9101) may use. Asymmetric only: a request object is a client instructing this server what to do with an authorization request, and it is verified against a key from the client's registration. Stated rather than inferred, which is the change. Nothing set ValidAlgorithms, so the accepted set was whatever the presented key happened to support — a set no operator could see, narrow, or find written down, and one discovery said nothing about. Discovery now advertises exactly this list, so a client is never told about an algorithm this server would then refuse. |
IdentityServerOptions.StrictJarValidation |
IdentityServer:StrictJarValidation |
bool |
false |
Whether a request object must be typed oauth-authz-req+jwt (RFC 9101 §10.8). Defaults to false.Duende's, measured from its 8.0.1 package. Not asked of a signed CIBA request, as Duende's CIBA validator does not. |
IdentityServerOptions.SupportedClientAssertionSigningAlgorithms |
IdentityServer:SupportedClientAssertionSigningAlgorithms |
ICollection<string> |
[ "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" ] |
The signing algorithms a client authentication assertion (RFC 7523) may use. The same rule at the other door, and the one where it matters more: this assertion is the client's credential. Advertised as token_endpoint_auth_signing_alg_values_supported. |
IdentityServerOptions.StrictClientAssertionAudienceValidation |
IdentityServer:StrictClientAssertionAudienceValidation |
bool |
false |
Whether every private_key_jwt client assertion is held to the strict rule: typed client-authentication+jwt, with exactly one audience, this server's issuer. Defaults to false.Duende 8.0.1's, measured from its PrivateKeyJwtSecretValidator, after draft-ietf-oauth-rfc7523bis and the audience-injection findings of 2025: an assertion naming several audiences, or a URL as its audience, can be one a client signed for another server. Off, an assertion may name this server's issuer or the URL it was sent to among its audiences, and its typ is not read — except that an assertion typed client-authentication+jwt is held to the strict rule whatever this says, as in Duende. The issuer is compared ignoring one trailing slash, as Duende compares it. New in 0.176.0; until then this server had no such option, and the parity matrix said its rule was unconditionally strict, which it was not. |
EndpointsOptions
Fdyay.IdentityServer.Configuration.EndpointsOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.Endpoints · configuration key IdentityServer:Endpoints
Controls which protocol endpoints are enabled.
A disabled endpoint stops serving — the request falls through the identity server middleware — and drops out of the discovery document. Both halves apply: an endpoint that is withdrawn from discovery but still answers is unadvertised rather than off, and so is absent from any surface inventory built from the document.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.Endpoints.EnableAuthorizeEndpoint |
IdentityServer:Endpoints:EnableAuthorizeEndpoint |
bool |
true |
Serves the authorize endpoint at connect/authorize and advertises it as authorization_endpoint. Defaults to true.While it is on, startup requires an authentication scheme to sign users in with — see UseIdentityServer(); a server that issues only machine tokens can turn it off instead. |
IdentityServerOptions.Endpoints.EnableTokenEndpoint |
IdentityServer:Endpoints:EnableTokenEndpoint |
bool |
true |
Serves the token endpoint at connect/token and advertises it as token_endpoint. Defaults to true. |
IdentityServerOptions.Endpoints.EnableUserInfoEndpoint |
IdentityServer:Endpoints:EnableUserInfoEndpoint |
bool |
true |
Serves the UserInfo endpoint at connect/userinfo and advertises it as userinfo_endpoint. Defaults to true. |
IdentityServerOptions.Endpoints.EnableDiscoveryEndpoint |
IdentityServer:Endpoints:EnableDiscoveryEndpoint |
bool |
true |
Serves the discovery document. Also governs the JWKS endpoint, which has no separate flag. |
IdentityServerOptions.Endpoints.EnableOAuth2MetadataEndpoint |
IdentityServer:Endpoints:EnableOAuth2MetadataEndpoint |
bool |
true |
Serves the OAuth 2.0 authorization server metadata (RFC 8414) at /.well-known/oauth-authorization-server: the discovery document, for a client that reads OAuth's well-known path rather than OpenID Connect's. Defaults to true, as in Duende.Independent of EndpointsOptions.EnableDiscoveryEndpoint, as Duende's is. |
IdentityServerOptions.Endpoints.EnableJwtRequestUri |
IdentityServer:Endpoints:EnableJwtRequestUri |
bool |
false |
Whether this server will fetch a JAR (RFC 9101) request object from a request_uri the client hosts. Defaults to false.Off by default because it is an outbound request to a location the client chooses: an authorization request naming an internal address would have this server fetch it. Request objects sent by value in request need no such fetch and are always accepted.Unrelated to the request_uri of PAR (RFC 9126), which is an opaque reference this server issued and is always on. The two are told apart by PAR's registered URN prefix. |
IdentityServerOptions.Endpoints.EnableEndSessionEndpoint |
IdentityServer:Endpoints:EnableEndSessionEndpoint |
bool |
true |
Serves the end-session (RP-initiated signout) endpoint at connect/endsession and advertises it as end_session_endpoint. Defaults to true. |
IdentityServerOptions.Endpoints.EnableCheckSessionEndpoint |
IdentityServer:Endpoints:EnableCheckSessionEndpoint |
bool |
true |
Serves the check-session iframe of OpenID Connect Session Management 1.0, and governs whether the document advertises check_session_iframe. |
IdentityServerOptions.Endpoints.EnableTokenRevocationEndpoint |
IdentityServer:Endpoints:EnableTokenRevocationEndpoint |
bool |
true |
Serves the token revocation endpoint (RFC 7009) at connect/revocation and advertises it as revocation_endpoint. Defaults to true. |
IdentityServerOptions.Endpoints.EnableIntrospectionEndpoint |
IdentityServer:Endpoints:EnableIntrospectionEndpoint |
bool |
true |
Serves the token introspection endpoint (RFC 7662) at connect/introspect and advertises it as introspection_endpoint. Defaults to true. |
IdentityServerOptions.Endpoints.EnablePushedAuthorizationEndpoint |
IdentityServer:Endpoints:EnablePushedAuthorizationEndpoint |
bool |
true |
Serves the pushed authorization request endpoint (RFC 9126) at connect/par and advertises it as pushed_authorization_request_endpoint. Defaults to true.Turning it off while PushedAuthorization.Required is true is refused at startup, because no client could then obtain the request_uri every authorization request would need. |
IdentityServerOptions.Endpoints.EnableDeviceAuthorizationEndpoint |
IdentityServer:Endpoints:EnableDeviceAuthorizationEndpoint |
bool |
true |
Serves the device authorization endpoint (RFC 8628) at connect/deviceauthorization and advertises it as device_authorization_endpoint. Defaults to true. |
IdentityServerOptions.Endpoints.EnableBackchannelAuthenticationEndpoint |
IdentityServer:Endpoints:EnableBackchannelAuthenticationEndpoint |
bool |
false |
Serves the backchannel authentication endpoint of OpenID Connect CIBA Core 1.0. Defaults to false — the only endpoint here that does.Every other endpoint can answer a request with what this library alone knows. This one cannot: a backchannel request names a user who is not present, so serving it needs a host-supplied way to resolve that name ( IBackchannelAuthenticationUserValidator) and a host-supplied way to reach the person behind it (IBackchannelAuthenticationUserNotificationService). On by default would mean a discovery document advertising an endpoint that answers every request with a 500, for every host that upgraded without asking for CIBA.Turning it on without registering both is refused at startup rather than discovered on the first request — see UseIdentityServer(). |
IdentityServerOptions.Endpoints.EnableSamlSigninEndpoint |
IdentityServer:Endpoints:EnableSamlSigninEndpoint |
bool |
false |
Serves the SAML 2.0 single sign-on endpoint, and the IdP-initiated door beneath it. Defaults to false, as Duende's does; AddSaml switches it on.The four SAML switches are off here because the endpoints they govern exist only once AddSaml registers them, and AddSaml turns all four on with a Configure<IdentityServerOptions> of its own — Duende's arrangement, measured. A host switching one off configures after AddSaml, so its setting is applied last. |
IdentityServerOptions.Endpoints.EnableSamlSigninCallbackEndpoint |
IdentityServer:Endpoints:EnableSamlSigninCallbackEndpoint |
bool |
false |
Serves the SAML 2.0 sign-in callback, where the browser comes back from the login page to have its sign-on answered. Defaults to false, as Duende's does; AddSaml switches it on. |
IdentityServerOptions.Endpoints.EnableSamlLogoutEndpoint |
IdentityServer:Endpoints:EnableSamlLogoutEndpoint |
bool |
false |
Serves the SAML 2.0 single logout endpoint. Defaults to false, as Duende's does; AddSaml switches it on. |
IdentityServerOptions.Endpoints.EnableSamlMetadataEndpoint |
IdentityServer:Endpoints:EnableSamlMetadataEndpoint |
bool |
false |
Serves the SAML 2.0 metadata document. Defaults to false, as Duende's does; AddSaml switches it on. |
DiscoveryOptions
Fdyay.IdentityServer.Configuration.DiscoveryOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.Discovery · configuration key IdentityServer:Discovery
Controls what is emitted in the discovery document.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.Discovery.ShowEndpoints |
IdentityServer:Discovery:ShowEndpoints |
bool |
true |
Whether discovery lists the endpoint URLs (authorization_endpoint, token_endpoint and the rest) and the members that describe them, such as request_parameter_supported. On by default.Only enabled endpoints are listed either way; see EndpointsOptions. |
IdentityServerOptions.Discovery.ShowKeySet |
IdentityServer:Discovery:ShowKeySet |
bool |
true |
Whether discovery lists jwks_uri and the key set is served there. Duende's; on by default.Until 0.139.0 the key set was served with this off, at a path the document no longer named. |
IdentityServerOptions.Discovery.ShowIdentityScopes |
IdentityServer:Discovery:ShowIdentityScopes |
bool |
true |
Whether scopes_supported includes the enabled identity resources marked to show in discovery. On by default. |
IdentityServerOptions.Discovery.ShowApiScopes |
IdentityServer:Discovery:ShowApiScopes |
bool |
true |
Whether scopes_supported includes the enabled API scopes marked to show in discovery, plus offline_access. On by default. |
IdentityServerOptions.Discovery.ShowClaims |
IdentityServer:Discovery:ShowClaims |
bool |
true |
Whether discovery lists claims_supported: the user claims of every enabled identity resource, API resource and API scope. On by default. |
IdentityServerOptions.Discovery.ShowResponseTypes |
IdentityServer:Discovery:ShowResponseTypes |
bool |
true |
Whether discovery lists response_types_supported, which is code only. On by default. |
IdentityServerOptions.Discovery.ShowResponseModes |
IdentityServer:Discovery:ShowResponseModes |
bool |
true |
Whether discovery lists response_modes_supported. Duende's; on by default.Until 0.130.0 the list went with DiscoveryOptions.ShowResponseTypes; Duende has a switch of its own for it. |
IdentityServerOptions.Discovery.ShowGrantTypes |
IdentityServer:Discovery:ShowGrantTypes |
bool |
true |
Whether discovery lists grant_types_supported: the built-in grants, less CIBA while its endpoint is off, and the host's extension grants when DiscoveryOptions.ShowExtensionGrantTypes is on. On by default. |
IdentityServerOptions.Discovery.ShowExtensionGrantTypes |
IdentityServer:Discovery:ShowExtensionGrantTypes |
bool |
true |
Whether grant_types_supported lists the extension grants a host registered. Duende's; on by default. |
IdentityServerOptions.Discovery.ShowTokenEndpointAuthenticationMethods |
IdentityServer:Discovery:ShowTokenEndpointAuthenticationMethods |
bool |
true |
Whether discovery lists token_endpoint_auth_methods_supported, and beside it the client-assertion algorithms when private_key_jwt is one of them. Duende's; on by default. |
IdentityServerOptions.Discovery.ShowRevocationEndpointAuthenticationMethods |
IdentityServer:Discovery:ShowRevocationEndpointAuthenticationMethods |
bool |
true |
Whether discovery lists revocation_endpoint_auth_methods_supported (RFC 8414 §2), and its algorithms as for DiscoveryOptions.ShowTokenEndpointAuthenticationMethods. Duende's; on by default. |
IdentityServerOptions.Discovery.ShowIntrospectionEndpointAuthenticationMethods |
IdentityServer:Discovery:ShowIntrospectionEndpointAuthenticationMethods |
bool |
true |
Whether discovery lists introspection_endpoint_auth_methods_supported (RFC 8414 §2), and its algorithms as for DiscoveryOptions.ShowTokenEndpointAuthenticationMethods. Duende's; on by default. |
IdentityServerOptions.Discovery.ExpandRelativePathsInCustomEntries |
IdentityServer:Discovery:ExpandRelativePathsInCustomEntries |
bool |
true |
Whether a DiscoveryOptions.CustomEntries string starting ~/ is expanded to a URL under the issuer. Duende's; on by default. |
IdentityServerOptions.Discovery.ResponseCacheInterval |
IdentityServer:Discovery:ResponseCacheInterval |
int? |
null |
The max-age, in seconds, of the discovery document's and the key set's Cache-Control header; zero sends no-store. Duende's; null by default, which sends no Cache-Control header. |
IdentityServerOptions.Discovery.EnableDiscoveryDocumentCache |
IdentityServer:Discovery:EnableDiscoveryDocumentCache |
bool |
false |
Whether the discovery document is kept in the IDistributedCache. Duende's; off by default. |
IdentityServerOptions.Discovery.DiscoveryDocumentCacheDuration |
IdentityServer:Discovery:DiscoveryDocumentCacheDuration |
TimeSpan |
00:01:00 |
How long a cached discovery document is served. Duende's; 1 minute by default. |
IdentityServerOptions.Discovery.CustomEntries |
IdentityServer:Discovery:CustomEntries |
Dictionary<string, object> |
{ } |
Members added to the discovery document after its own; one the document already has is not replaced. Duende's. |
KeyManagementOptions
Fdyay.IdentityServer.Configuration.KeyManagementOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.KeyManagement · configuration key IdentityServer:KeyManagement
Automatic signing-key management options.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.KeyManagement.Enabled |
IdentityServer:KeyManagement:Enabled |
bool |
true |
Whether automatic key management is enabled. Defaults to true. |
IdentityServerOptions.KeyManagement.RotationInterval |
IdentityServer:KeyManagement:RotationInterval |
TimeSpan |
90.00:00:00 |
How long a key is used for signing before rotation. Defaults to 90 days. |
IdentityServerOptions.KeyManagement.PropagationTime |
IdentityServer:KeyManagement:PropagationTime |
TimeSpan |
14.00:00:00 |
How long before rotation a new key is announced. Defaults to 14 days. |
IdentityServerOptions.KeyManagement.RetentionDuration |
IdentityServer:KeyManagement:RetentionDuration |
TimeSpan |
14.00:00:00 |
How long a retired key remains published in the JWKS. Defaults to 14 days. |
IdentityServerOptions.KeyManagement.KeyCacheDuration |
IdentityServer:KeyManagement:KeyCacheDuration |
TimeSpan |
1.00:00:00 |
How long loaded key material is cached in memory. Defaults to 24 hours. Held to at most half of KeyManagementOptions.PropagationTime, as Duende holds it, so a new key is seen well before it signs. |
IdentityServerOptions.KeyManagement.InitializationDuration |
IdentityServer:KeyManagement:InitializationDuration |
TimeSpan |
00:05:00 |
How long after the first key is created every instance treats the key set as new. Defaults to 5 minutes, as Duende's does; zero turns the initialisation window off. Duende 8.0.1's, measured. While every key in the store is this young, an instance that has just created one waits KeyManagementOptions.InitializationSynchronizationDelay and reads the store again, so that instances starting together on one store see each other's keys, and caches the set for KeyManagementOptions.InitializationKeyCacheDuration rather than KeyManagementOptions.KeyCacheDuration. With the oldest current key signing, they converge on one. |
IdentityServerOptions.KeyManagement.InitializationSynchronizationDelay |
IdentityServer:KeyManagement:InitializationSynchronizationDelay |
TimeSpan |
00:00:05 |
How long an instance that created a key during the initialisation window waits before reading the store again. Defaults to 5 seconds, as Duende's does. Not waited for on the in-memory store, which no other instance can share: there is nobody's key to wait for. Duende has no in-memory store. |
IdentityServerOptions.KeyManagement.InitializationKeyCacheDuration |
IdentityServer:KeyManagement:InitializationKeyCacheDuration |
TimeSpan |
00:01:00 |
How long the key set is cached while every key is within the initialisation window. Defaults to 1 minute, as Duende's does. |
IdentityServerOptions.KeyManagement.DeleteRetiredKeys |
IdentityServer:KeyManagement:DeleteRetiredKeys |
bool |
true |
Whether a key past KeyManagementOptions.KeyRetirementAge is deleted from the store. Defaults to true, as Duende's does.Off, a retired key stays in the store and is neither published nor used. |
IdentityServerOptions.KeyManagement.RsaKeySize |
IdentityServer:KeyManagement:RsaKeySize |
int |
2048 |
The RSA key size in bits for generated keys. Defaults to 2048. |
IdentityServerOptions.KeyManagement.SigningAlgorithms |
IdentityServer:KeyManagement:SigningAlgorithms |
ICollection<SigningAlgorithmOptions> |
[ ] |
The algorithms a key is kept for, one current key each; the first signs when a client or resource names none. Empty by default, which is RS256 alone, as Duende's is. Duende 8.0.1's, measured: RS256/384/512, PS256/384/512 and ES256/384/512, each at most once, and SigningAlgorithmOptions.UseX509Certificate for the RSA families only. Until 0.137.0 this was SigningAlgorithm, a single RSA algorithm. |
IdentityServerOptions.KeyManagement.AllowedSigningAlgorithmNames |
IdentityServer:KeyManagement:AllowedSigningAlgorithmNames |
IEnumerable<string> |
[ "RS256" ] |
The names of KeyManagementOptions.SigningAlgorithms, else RS256. |
IdentityServerOptions.KeyManagement.KeyPath |
IdentityServer:KeyManagement:KeyPath |
string |
"{working directory}/keys" |
Where the default key store writes keys. Defaults to a keys directory under the working directory, as Duende's does.Read by the default FileSystemKeyStore; a host that registers its own store ignores it. |
IdentityServerOptions.KeyManagement.DataProtectKeys |
IdentityServer:KeyManagement:DataProtectKeys |
bool |
true |
Whether a key is protected with ASP.NET Core Data Protection before it is stored. Defaults to true, as Duende's does. Off, the private key is stored as it is; for a store that protects what it holds by other means. |
SigningAlgorithmOptions
Fdyay.IdentityServer.Configuration.SigningAlgorithmOptions in Fdyay.IdentityServer.Core · each item of IdentityServerOptions.KeyManagement.SigningAlgorithms[i] · configuration key IdentityServer:KeyManagement:SigningAlgorithms:{index}
An algorithm automatic key management keeps a key for. Duende's SigningAlgorithmOptions.
An item has no parameterless constructor, so there is no default to read: each is set where it is created.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.KeyManagement.SigningAlgorithms[i].Name |
IdentityServer:KeyManagement:SigningAlgorithms:{index}:Name |
string |
— | The algorithm, e.g. RS256, PS384, ES256. |
IdentityServerOptions.KeyManagement.SigningAlgorithms[i].UseX509Certificate |
IdentityServer:KeyManagement:SigningAlgorithms:{index}:UseX509Certificate |
bool |
— | Whether the key is wrapped in a self-signed certificate, published as x5c and x5t. RSA only, as Duende's is. |
UserInteractionOptions
Fdyay.IdentityServer.Configuration.UserInteractionOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.UserInteraction · configuration key IdentityServer:UserInteraction
Paths the protocol endpoints redirect to for interactive login, consent and signout.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.UserInteraction.LoginUrl |
IdentityServer:UserInteraction:LoginUrl |
string |
"/account/login" |
The login page path. Defaults to /account/login. |
IdentityServerOptions.UserInteraction.ConsentUrl |
IdentityServer:UserInteraction:ConsentUrl |
string |
"/account/consent" |
The consent page path. Defaults to /account/consent. |
IdentityServerOptions.UserInteraction.LogoutUrl |
IdentityServer:UserInteraction:LogoutUrl |
string |
"/account/logout" |
The logout page path. Defaults to /account/logout. |
IdentityServerOptions.UserInteraction.ErrorUrl |
IdentityServer:UserInteraction:ErrorUrl |
string |
"/account/error" |
The error page path. Defaults to /account/error. |
IdentityServerOptions.UserInteraction.ReturnUrlParameter |
IdentityServer:UserInteraction:ReturnUrlParameter |
string |
"returnUrl" |
A second name the login page also accepts a return URL under. Defaults to returnUrl.No longer emitted by anything. Until 0.56.0 the SAML single sign-on endpoint used this while the authorize endpoint used UserInteractionOptions.LoginReturnUrlParameter — two names for one destination, which is how a host that renamed the documented one broke SAML sign-on while OIDC kept working. Both redirects now emit UserInteractionOptions.LoginReturnUrlParameter.Kept, and still read, so a host that had configured only this one is not broken by the unification: the login page tries UserInteractionOptions.LoginReturnUrlParameter first and falls back to this. Prefer the specific one. The same shape as 0.52.0's NameIdClaimType fix — one side owns the canonical spelling and the other is an additional mapping rather than a replacement. |
IdentityServerOptions.UserInteraction.LoginReturnUrlParameter |
IdentityServer:UserInteraction:LoginReturnUrlParameter |
string |
"returnUrl" |
The return-url query parameter name for the login redirect. Defaults to returnUrl.Separate from the consent parameter so a host can route the two redirects differently. |
IdentityServerOptions.UserInteraction.ConsentReturnUrlParameter |
IdentityServer:UserInteraction:ConsentReturnUrlParameter |
string |
"returnUrl" |
The return-url query parameter name for the consent redirect. Defaults to returnUrl.Separate from the login parameter so a host can route the two redirects differently. |
IdentityServerOptions.UserInteraction.CreateAccountUrl |
IdentityServer:UserInteraction:CreateAccountUrl |
string? |
null |
The create-account page, for a request with prompt=create. Defaults to null. Duende's.Duende 8.0.1's, measured: unset, create is not among the supported prompt values and a request asking for it is refused as an unsupported prompt; set, UseIdentityServer adds create to UserInteractionOptions.PromptValuesSupported, so discovery publishes it and the authorize endpoint sends such a request here. |
IdentityServerOptions.UserInteraction.CreateAccountReturnUrlParameter |
IdentityServer:UserInteraction:CreateAccountReturnUrlParameter |
string |
"returnUrl" |
The return-url query parameter name for the create-account redirect. Defaults to returnUrl. Duende's. |
IdentityServerOptions.UserInteraction.CustomRedirectReturnUrlParameter |
IdentityServer:UserInteraction:CustomRedirectReturnUrlParameter |
string |
"returnUrl" |
The return-url query parameter name for a redirect an interaction generator asks for. Defaults to returnUrl. Duende's.Appended to InteractionResponse.RedirectUrl when a host's IAuthorizeInteractionResponseGenerator sends the user somewhere of its own before the request is answered. |
IdentityServerOptions.UserInteraction.PromptValuesSupported |
IdentityServer:UserInteraction:PromptValuesSupported |
ICollection<string> |
[ "none", "login", "consent", "select_account" ] |
The prompt values the authorize endpoint accepts, published as prompt_values_supported. Duende's.Duende 8.0.1's, measured: none, login, consent and select_account, with create added at startup when UserInteractionOptions.CreateAccountUrl is set. A request carrying any other value is refused (invalid_request, "Unsupported prompt mode"); until 0.142.0 an unknown value was accepted and ignored. A value added here needs an IAuthorizeInteractionResponseGenerator that acts on it. |
IdentityServerOptions.UserInteraction.AllowOriginInReturnUrl |
IdentityServer:UserInteraction:AllowOriginInReturnUrl |
bool |
false |
Whether a return URL may be absolute when it names this server's own origin. Defaults to false. Duende's.Duende 8.0.1's, measured: read by the OpenID Connect and SAML return-URL parsers, which take this server's origin off the front of an absolute return URL — compared ignoring case — and then judge what is left as they judge any other. Ours, decided 2026-10-14: it also decides whether an interaction page configured as an absolute URL is handed an absolute return URL. Duende hands one whatever the option, so a page on this server written that way stops resuming requests until the option is on; here, off, every page is handed the relative return URL it always was. |
IdentityServerOptions.UserInteraction.LogoutIdParameter |
IdentityServer:UserInteraction:LogoutIdParameter |
string |
"logoutId" |
The logout-id query parameter name. Defaults to logoutId. |
IdentityServerOptions.UserInteraction.ErrorIdParameter |
IdentityServer:UserInteraction:ErrorIdParameter |
string |
"errorId" |
The error-id query parameter name. Defaults to errorId. |
IdentityServerOptions.UserInteraction.ShowErrorDetail |
IdentityServer:UserInteraction:ShowErrorDetail |
bool |
false |
Whether the error page may show the error code, description and requested client id. Defaults to false.Off by default so a host that configures nothing discloses nothing: end users see a generic message and the reference id only. Turn it on in environments where showing protocol detail to whoever hit the page is acceptable. |
IdentityServerOptions.UserInteraction.ErrorMessageLifetime |
IdentityServer:UserInteraction:ErrorMessageLifetime |
TimeSpan |
00:05:00 |
How long a stored error context can be read back. Defaults to 5 minutes. Long enough for the redirect to the error page, short enough not to accumulate. |
IdentityServerOptions.UserInteraction.ConsentMessageLifetime |
IdentityServer:UserInteraction:ConsentMessageLifetime |
TimeSpan |
00:05:00 |
How long a recorded consent decision can be read back. Defaults to 5 minutes. Long enough for the redirect from the consent page back to the authorize endpoint, and no longer. |
PushedAuthorizationOptions
Fdyay.IdentityServer.Configuration.PushedAuthorizationOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.PushedAuthorization · configuration key IdentityServer:PushedAuthorization
Server-wide settings for pushed authorization requests.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.PushedAuthorization.Lifetime |
IdentityServer:PushedAuthorization:Lifetime |
TimeSpan |
00:10:00 |
How long a pushed request stays redeemable. Defaults to ten minutes. Short by design: the window only has to cover the redirect from the client to the browser and on to the authorize endpoint, and a reference value is a bearer credential for the whole request while it lives. A client may shorten it further per request; it may not lengthen it past this. |
IdentityServerOptions.PushedAuthorization.Required |
IdentityServer:PushedAuthorization:Required |
bool |
false |
Whether every client must push its authorization requests. Defaults to false. Individual clients can require it on their own with Client.RequirePushedAuthorization; this makes it server-wide, which is what an installation with no legacy clients left should do. |
IdentityServerOptions.PushedAuthorization.AllowUnregisteredPushedRedirectUris |
IdentityServer:PushedAuthorization:AllowUnregisteredPushedRedirectUris |
bool |
false |
Whether a confidential client's pushed request may name a redirect URI it did not register. Defaults to false. Duende's, measured from its 8.0.1 package (RFC 9126 §2.4): a client that authenticated to push has proved who it is, so the redirect URI it pushes is its own word rather than a browser's. Only a client with RequireClientSecret, only for a pushed request and its redemption, and such a client then needs no registered redirect URI at all. |
CorsOptions
Fdyay.IdentityServer.Configuration.CorsOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.Cors · configuration key IdentityServer:Cors
CORS settings for the protocol endpoints.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.Cors.CorsPaths |
IdentityServer:Cors:CorsPaths |
ICollection<string> |
[ ".well-known/openid-configuration", ".well-known/openid-configuration/jwks", "connect/userinfo", "connect/token", "connect/revocation" ] |
The protocol endpoint paths CORS is applied to, relative and without a leading slash. Defaults to the endpoints a browser-based client calls directly: discovery and its key set, user info, token and revocation. Authorize and end session are absent because a browser reaches them by navigation rather than by script, and introspection because it is a resource server's call, not a browser's. These are the values in ProtocolRoutePaths. They are spelled out here because the paths live in the hosting assembly and these options do not depend on it; a test asserts the two agree. |
IdentityServerOptions.Cors.CorsPolicyName |
IdentityServer:Cors:CorsPolicyName |
string |
"IdentityServer" |
The name of the ASP.NET Core CORS policy evaluated for protocol endpoint requests. The policy decides which origins are allowed by asking the registered ICorsPolicyService. Register a different implementation of that to change the answer, rather than redefining a policy under this name. |
IdentityServerOptions.Cors.PreflightCacheDuration |
IdentityServer:Cors:PreflightCacheDuration |
TimeSpan? |
null |
The Access-Control-Max-Age value sent on preflight responses.Null by default, which emits no header and leaves the preflight cache duration to the browser. |
DeviceFlowOptions
Fdyay.IdentityServer.Configuration.DeviceFlowOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.DeviceFlow · configuration key IdentityServer:DeviceFlow
Settings for the device authorization grant (RFC 8628).
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.DeviceFlow.Lifetime |
IdentityServer:DeviceFlow:Lifetime |
int |
300 |
How long the user has to approve a device, in seconds. Defaults to 5 minutes. Long enough to walk to another device and type a code, short enough that an abandoned request stops being approvable soon after the user has forgotten about it. |
IdentityServerOptions.DeviceFlow.DefaultUserCodeType |
IdentityServer:DeviceFlow:DefaultUserCodeType |
string |
"Readable" |
The IUserCodeGenerator.UserCodeType used for a client that names none. Defaults to UserCodeTypes.Readable.Duende defaults to its nine-digit numeric code, about 30 bits; this server's default has been the twelve character readable one, a little over 51, since 0.23.0, and stays so — a user code names a pending authorization to anybody who guesses it, so the weaker form is opted into per client or here, not inherited. |
IdentityServerOptions.DeviceFlow.Interval |
IdentityServer:DeviceFlow:Interval |
int |
5 |
The minimum seconds a device should wait between polls. Defaults to 5. Returned as interval, and enforced: polling faster is answered with slow_down. |
IdentityServerOptions.DeviceFlow.VerificationUrl |
IdentityServer:DeviceFlow:VerificationUrl |
string |
"/device" |
The path the user is sent to in order to enter their code. Defaults to /device. |
IdentityServerOptions.DeviceFlow.UserCodeParameter |
IdentityServer:DeviceFlow:UserCodeParameter |
string |
"userCode" |
The query parameter carrying the user code on the verification URL. Defaults to userCode.Used to build verification_uri_complete, which a device can render as a QR code. |
CibaOptions
Fdyay.IdentityServer.Configuration.CibaOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.Ciba · configuration key IdentityServer:Ciba
Settings for backchannel authentication (OpenID Connect CIBA Core 1.0).
Nothing here names a delivery mode: which one a client gets is its registration's BackChannelTokenDeliveryMode, and all three are delivered — poll since 0.27.0, ping since 0.72.0 and push since 0.73.0. What is server-wide is how long a callback may take, and whether this host checks user codes.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.Ciba.Lifetime |
IdentityServer:Ciba:Lifetime |
int |
300 |
How long a user has to answer a request, in seconds. Defaults to 5 minutes. Longer than a device code's window would be, and for the opposite reason: the user is not standing at a screen waiting to type something, they are being interrupted. Short enough that a request nobody answered stops being answerable while the person who triggered it still remembers it. |
IdentityServerOptions.Ciba.MaximumLifetime |
IdentityServer:Ciba:MaximumLifetime |
int |
600 |
The longest lifetime a client may ask for with requested_expiry. Defaults to 10 minutes.A ceiling rather than a second default: CibaOptions.Lifetime is what a client that asks for nothing gets, and this is as far as one that asks may go. Without the cap a client chooses how long an unanswered request stays approvable, which is not the client's decision to make. |
IdentityServerOptions.Ciba.Interval |
IdentityServer:Ciba:Interval |
int |
5 |
The minimum seconds a client should wait between polls. Defaults to 5. Returned as interval, and enforced: polling faster is answered with slow_down. A client may be given a longer one of its own with Client.PollingInterval. |
IdentityServerOptions.Ciba.NotificationTimeout |
IdentityServer:Ciba:NotificationTimeout |
TimeSpan |
00:00:10 |
How long to wait for a client's ping notification endpoint. Defaults to 10 seconds. Ten seconds because that is what every other outbound hop in this tree waits — the back-channel logout notification, the JAR request_uri fetch, a client-credentials token request — and for the reason they give: somebody is waiting on the answer.Here that somebody is the user, which is easy to miss. The notification is sent while recording their decision, so their "approve" does not come back until the client's endpoint has answered or this elapses. A generous value would let a client that registered for ping and then stopped answering hold up the person approving its requests. For a ping, elapsing loses nothing but the callback: the answer is recorded first and stays redeemable by polling, and the failure is raised as BackChannelAuthenticationNotificationFailureEvent. For a push it loses the tokens, which were minted to travel in the callback and which the client may not poll for — the same event records it, and that is the trade a client makes by registering for push. |
IdentityServerOptions.Ciba.UserCodeParameterSupported |
IdentityServer:Ciba:UserCodeParameterSupported |
bool |
false |
Whether this host's IBackchannelAuthenticationUserValidator checks a user_code. Defaults to false.This server cannot check a user code — it is a secret between the user and the host — so this is the host declaring that its validator does. It decides what discovery says ( backchannel_user_code_parameter_supported) and whether a request carrying a user_code is accepted. Off, one is refused rather than ignored: a client that collected a PIN from somebody and sent it believes the PIN gates the request, and accepting it with nothing checking would make that belief false while every response looked right. Duende has no such option; this is the difference. |
BackChannelLogoutOptions
Fdyay.IdentityServer.Configuration.BackChannelLogoutOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.BackChannelLogout · configuration key IdentityServer:BackChannelLogout
Back-channel logout notification behaviour (OpenID Connect Back-Channel Logout 1.0).
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.BackChannelLogout.Timeout |
IdentityServer:BackChannelLogout:Timeout |
TimeSpan |
00:00:10 |
How long to wait for one relying party's logout endpoint before giving up on it. Per relying party, not for the whole fan-out. Sign-out must not be held open by a client that has gone away, and the user is waiting on the response, so this is deliberately short. |
IdentityServerOptions.BackChannelLogout.LogoutTokenLifetime |
IdentityServer:BackChannelLogout:LogoutTokenLifetime |
int |
300 |
Lifetime of an issued logout token, in seconds. The token is delivered directly to the relying party and consumed immediately, so this only has to cover clock skew and the request itself. |
MutualTlsOptions
Fdyay.IdentityServer.Configuration.MutualTlsOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.MutualTls · configuration key IdentityServer:MutualTls
Mutual-TLS client authentication and certificate-bound access tokens (RFC 8705).
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.MutualTls.ClientCertificateAuthenticationScheme |
IdentityServer:MutualTls:ClientCertificateAuthenticationScheme |
string |
"Certificate" |
The authentication scheme that must accept the client certificate before an mTLS alias is served. Defaults to Certificate, the name ASP.NET Core's certificate handler registers under, as Duende's does.Duende 8.0.1's, measured: a request to a connect/mtls/ alias is authenticated with this scheme first, and one it does not accept is refused with invalid_client before any endpoint runs. The handler — typically AddAuthentication().AddCertificate() — is where the chain, revocation and allowed issuers are checked; the client's registered thumbprint or name is still compared afterwards, as before. |
IdentityServerOptions.MutualTls.Enabled |
IdentityServer:MutualTls:Enabled |
bool |
false |
Whether the protocol endpoints are also served under connect/mtls/. Defaults to false.The aliases exist so that client certificates can be required on those paths without requiring them everywhere: a TLS listener asks for a certificate per host or per path, and asking for one at the authorize endpoint would prompt every browser user for a certificate they do not have. Turning this on only publishes the paths — the host still has to configure its listener to request a certificate there. The aliases are path-based only. A subdomain form exists in the wider ecosystem and is deliberately not offered here: nothing in these options names a domain, so no configuration promises one. |
IdentityServerOptions.MutualTls.AlwaysEmitConfirmationClaim |
IdentityServer:MutualTls:AlwaysEmitConfirmationClaim |
bool |
false |
Whether a token gets a cnf claim whenever the connection carried a client certificate, even if the client authenticated some other way. Defaults to false.Off by default because the certificate that authenticated the client is the one the client has committed to using, while a certificate that merely happened to be on the connection is not: binding a token to it makes every later call fail unless the client presents that same certificate again. |
EventsOptions
Fdyay.IdentityServer.Configuration.EventsOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.Events · configuration key IdentityServer:Events
Which kinds of event reach the sink.
Every flag defaults to false. Events carry client ids, subject ids and addresses, and where they end up is the host's decision rather than this server's — so raising them is opt-in, and a host that never configures a sink never emits anything anywhere.
The four are separate because they are wanted separately: a deployment that wants an alert on EventTypes.Error almost never wants a record of every successful token issuance, and one doing security monitoring wants EventTypes.Failure and nothing else.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.Events.RaiseSuccessEvents |
IdentityServer:Events:RaiseSuccessEvents |
bool |
false |
Raise events for operations that succeeded. |
IdentityServerOptions.Events.RaiseFailureEvents |
IdentityServer:Events:RaiseFailureEvents |
bool |
false |
Raise events for requests the server refused. |
IdentityServerOptions.Events.RaiseInformationEvents |
IdentityServer:Events:RaiseInformationEvents |
bool |
false |
Raise events that are neither a success nor a refusal. |
IdentityServerOptions.Events.RaiseErrorEvents |
IdentityServer:Events:RaiseErrorEvents |
bool |
false |
Raise events for faults in the server itself. |
IdentityServerOptions.Events.IncludeStackTraceInUnhandledExceptionEvents |
IdentityServer:Events:IncludeStackTraceInUnhandledExceptionEvents |
bool |
false |
Put the exception's stack trace, and its inner exceptions, in UnhandledExceptionEvent.Details. Off by default.Off, Details carries the exception's type and message. On, it carries Exception.ToString(), which is what Duende 8.0.1's always carries. A stack trace names this server's internals and sometimes the values it was working on, so it is the host's decision, made knowing where its sink sends things (the decision of 2026-10-13). Not Duende's: Duende has no switch, because it has no default without the stack. |
DPoPOptions
Fdyay.IdentityServer.Configuration.DPoPOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.DPoP · configuration key IdentityServer:DPoP
Options for DPoP proof validation (RFC 9449).
The other way to sender-constrain a token, and the one a client with no certificate can use. mTLS binds to something the transport already proved; DPoP binds to a key the client proves per request, which is why these options are almost entirely about time — a proof is only worth anything for as long as it cannot be replayed.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.DPoP.ProofTokenValidityDuration |
IdentityServer:DPoP:ProofTokenValidityDuration |
TimeSpan |
00:01:00 |
How long a proof stays acceptable after the iat it carries. Defaults to one minute.The window in which a stolen proof still works, so it wants to be short. It is not the only thing stopping a replay — every jti is remembered for at least this long — but it is what bounds how much has to be remembered. |
IdentityServerOptions.DPoP.ClientClockSkew |
IdentityServer:DPoP:ClientClockSkew |
TimeSpan |
00:05:00 |
How far a client's clock may run ahead of this server's. Defaults to five minutes. Separate from the validity window because they answer different questions: the window is how long a proof lives, this is how wrong the client's idea of "now" may be. Folding them together would mean tolerating a skewed clock by keeping every proof alive longer, for every client. |
IdentityServerOptions.DPoP.ServerClockSkew |
IdentityServer:DPoP:ServerClockSkew |
TimeSpan |
00:00:00 |
How far the servers in a farm may disagree about the time when a DPoP nonce one of them issued is checked by another. Defaults to zero, as in Duende. A nonce is accepted for DPoPOptions.ProofTokenValidityDuration after it was issued, plus this. |
IdentityServerOptions.DPoP.SupportedSigningAlgorithms |
IdentityServer:DPoP:SupportedSigningAlgorithms |
ICollection<string> |
[ "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" ] |
The signing algorithms a proof may use. Asymmetric only, and stated rather than inferred: a proof is a signature by a key the client embeds in the proof itself, so accepting a symmetric algorithm would accept a proof signed by a key the attacker chose. Discovery advertises exactly this list, so a client is never told about an algorithm this server would then refuse. |
InputLengthRestrictions
Fdyay.IdentityServer.Configuration.InputLengthRestrictions in Fdyay.IdentityServer.Core · at IdentityServerOptions.InputLengths · configuration key IdentityServer:InputLengths
How long each protocol parameter this server reads may be.
Mostly an abuse control: every value here arrives from a caller, several of them unauthenticated, and each is then split, compared, hashed, stored or logged. A bound is the cheapest thing that stops any of those being asked to do unbounded work.
InputLengthRestrictions.CodeVerifierMinLength is the exception, and it is not about abuse at all. RFC 7636 §4.1 requires a code_verifier of 43 to 128 characters because PKCE's whole protection is that an attacker holding an intercepted authorization code cannot produce the verifier. That attacker also holds the code_challenge — it travelled in the authorization request — so a short verifier is brute-forced offline and the code redeemed. The floor is what makes the search infeasible.
Every property here is enforced. A limit that nothing reads would be a setting an operator could tune while the request it names went on unbounded, which is the shape §1 of the parity matrix exists to remove — so parameters this server does not yet bound are absent rather than present and ignored.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.InputLengths.ClientId |
IdentityServer:InputLengths:ClientId |
int |
100 |
Maximum length of client_id. Defaults to 100. |
IdentityServerOptions.InputLengths.Scope |
IdentityServer:InputLengths:Scope |
int |
300 |
Maximum length of scope, the whole space-delimited list. Defaults to 300. |
IdentityServerOptions.InputLengths.RedirectUri |
IdentityServer:InputLengths:RedirectUri |
int |
400 |
Maximum length of redirect_uri. Defaults to 400. |
IdentityServerOptions.InputLengths.Nonce |
IdentityServer:InputLengths:Nonce |
int |
300 |
Maximum length of nonce. Defaults to 300. |
IdentityServerOptions.InputLengths.State |
IdentityServer:InputLengths:State |
int |
2000 |
Maximum length of state. Defaults to 2000.The most generous bound here, because state is the one parameter clients legitimately pack: it is theirs, opaque to this server, and often carries an encoded return context. It is also the only one echoed back, which is why exceeding it is answered without a redirect — see the authorize validator. |
IdentityServerOptions.InputLengths.LoginHint |
IdentityServer:InputLengths:LoginHint |
int |
100 |
Maximum length of login_hint. Defaults to 100. |
IdentityServerOptions.InputLengths.AcrValues |
IdentityServer:InputLengths:AcrValues |
int |
300 |
Maximum length of acr_values. Defaults to 300. |
IdentityServerOptions.InputLengths.CodeChallengeMinLength |
IdentityServer:InputLengths:CodeChallengeMinLength |
int |
43 |
Minimum length of code_challenge (RFC 7636 §4.2). Defaults to 43. |
IdentityServerOptions.InputLengths.CodeChallengeMaxLength |
IdentityServer:InputLengths:CodeChallengeMaxLength |
int |
128 |
Maximum length of code_challenge. Defaults to 128. |
IdentityServerOptions.InputLengths.CodeVerifierMinLength |
IdentityServer:InputLengths:CodeVerifierMinLength |
int |
43 |
Minimum length of code_verifier (RFC 7636 §4.1). Defaults to 43.Lowering this weakens PKCE for every client, and lowering it far enough removes PKCE's protection entirely while leaving every part of the exchange looking correct. It is settable because the specification names a number and a host may have to meet an older client, not because it is a knob. |
IdentityServerOptions.InputLengths.CodeVerifierMaxLength |
IdentityServer:InputLengths:CodeVerifierMaxLength |
int |
128 |
Maximum length of code_verifier. Defaults to 128. |
IdentityServerOptions.InputLengths.BindingMessage |
IdentityServer:InputLengths:BindingMessage |
int |
64 |
Maximum length of a CIBA binding_message. Defaults to 64.Bounded by human patience rather than by storage: it exists to be read out and compared by a person on two devices, and a message nobody finishes comparing is a ceremony everyone learns to click through. |
IdentityServerOptions.InputLengths.ClientNotificationToken |
IdentityServer:InputLengths:ClientNotificationToken |
int |
1024 |
The longest client_notification_token accepted. Defaults to 1024.Client-supplied and stored, so it is bounded like every other string a client sends. CIBA Core §7.1 asks for at least 128 bits of entropy and sets no ceiling, so the ceiling here is only about not storing an arbitrary amount of someone else's data: anything a client can reasonably mint fits far inside it. |
IdentityServerOptions.InputLengths.IdTokenHint |
IdentityServer:InputLengths:IdTokenHint |
int |
4000 |
The longest id_token_hint accepted. Defaults to 4000.Checked before the token is parsed, so a client cannot make this server verify a signature over an arbitrary amount of input. Generous because an identity token carries whatever profile claims a client is entitled to, and one this server signed should never be refused for being this server's own size. |
IdentityServerOptions.InputLengths.UserCode |
IdentityServer:InputLengths:UserCode |
int |
100 |
The longest CIBA user_code accepted. Defaults to 100.CIBA's only — the device flow's user code is a different thing under the same name, one this server generates rather than one a client sends. A user code is a PIN or a password, so the bound is about not handing a host's validator an arbitrary amount of input to compare, not about what a real one looks like. |
IdentityServerOptions.InputLengths.LoginHintToken |
IdentityServer:InputLengths:LoginHintToken |
int |
4000 |
The longest CIBA login_hint_token accepted. Defaults to 4000.Duende's default, measured from its 8.0.1 package: a longer one is invalid_request. |
IdentityServerOptions.InputLengths.DeviceCode |
IdentityServer:InputLengths:DeviceCode |
int |
100 |
The longest device_code accepted at the token endpoint. Defaults to 100.Duende's default, measured from its 8.0.1 package: a longer one is invalid_grant, before the store is asked. |
IdentityServerOptions.InputLengths.ResourceIndicator |
IdentityServer:InputLengths:ResourceIndicator |
int |
512 |
The longest resource indicator accepted (RFC 8707). Defaults to 512.Duende's default, measured from its 8.0.1 package; an API's URI has no reason to come near it. |
IdentityServerOptions.InputLengths.DPoPProofToken |
IdentityServer:InputLengths:DPoPProofToken |
int |
4000 |
The longest DPoP proof accepted, at the token and pushed authorization endpoints. Defaults to 4000. Duende's default, measured from its 8.0.1 package. Checked before the proof is parsed, so a client cannot make this server verify a signature over an arbitrary amount of input; a proof is a header, a key and a few claims. |
IdentityServerOptions.InputLengths.ClientSecret |
IdentityServer:InputLengths:ClientSecret |
int |
100 |
The longest client secret read from the Authorization header or the form. Defaults to 100.A longer one is not a credential: the parser reads nothing, as Duende's does, and the request is answered as one with no client authentication. The Authorization header as a whole may be no longer than the base64 of a client id and secret at their limits. |
IdentityServerOptions.InputLengths.UiLocale |
IdentityServer:InputLengths:UiLocale |
int |
100 |
The longest ui_locales accepted at the authorize endpoint. Defaults to 100. |
IdentityServerOptions.InputLengths.GrantType |
IdentityServer:InputLengths:GrantType |
int |
100 |
The longest grant_type accepted at the token endpoint. Defaults to 100; a longer one is unsupported_grant_type. |
IdentityServerOptions.InputLengths.AuthorizationCode |
IdentityServer:InputLengths:AuthorizationCode |
int |
100 |
The longest authorization code accepted at the token endpoint. Defaults to 100; a longer one is invalid_grant, before the store is asked. |
IdentityServerOptions.InputLengths.RefreshToken |
IdentityServer:InputLengths:RefreshToken |
int |
100 |
The longest refresh_token accepted at the token endpoint. Defaults to 100; a longer one is invalid_grant, before the store is asked. |
IdentityServerOptions.InputLengths.TokenHandle |
IdentityServer:InputLengths:TokenHandle |
int |
100 |
The longest reference-token handle accepted wherever an access token is validated. Defaults to 100. A JWT is held to InputLengthRestrictions.Jwt instead. Either too long is invalid_token before anything is looked up or verified. |
IdentityServerOptions.InputLengths.AuthenticationRequestId |
IdentityServer:InputLengths:AuthenticationRequestId |
int |
100 |
The longest CIBA auth_req_id accepted at the token endpoint. Defaults to 100; a longer one is invalid_grant. |
IdentityServerOptions.InputLengths.DPoPKeyThumbprint |
IdentityServer:InputLengths:DPoPKeyThumbprint |
int |
100 |
The longest dpop_jkt accepted at the authorize endpoint. Defaults to 100.A SHA-256 JWK thumbprint is 43 characters. |
IdentityServerOptions.InputLengths.Jwt |
IdentityServer:InputLengths:Jwt |
int |
51200 |
The longest request object accepted, by value or fetched, and the longest signed CIBA request. Defaults to 51200. Duende's default, measured from its 8.0.1 package, where it bounds the handler that reads the object. |
CspOptions
Fdyay.IdentityServer.Configuration.CspOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.Csp · configuration key IdentityServer:Csp
Content-Security-Policy settings for this server's own pages.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.Csp.Level |
IdentityServer:Csp:Level |
CspLevel |
Two |
The CSP version to write policies for. Defaults to CspLevel.Two.It decides two real things rather than a syntax flavour. frame-ancestors is Level 2, so at Level 1 the framing refusal rests entirely on X-Frame-Options — which is why lowering this without CspOptions.AddDeprecatedHeaders leaves the approval screens framable. Hash sources are Level 2 too, so the check-session iframe falls back to 'unsafe-inline' for its own script. |
IdentityServerOptions.Csp.AddDeprecatedHeaders |
IdentityServer:Csp:AddDeprecatedHeaders |
bool |
true |
Whether to also send the headers browsers used before CSP Level 2. Defaults to true.X-Frame-Options: DENY and X-Content-Security-Policy. Both are superseded and both are still the only thing an old browser reads, and the page they protect is one where a single click grants an application access to a user's data. Turning them off is for a deployment that knows what its users run. |
ValidationOptions
Fdyay.IdentityServer.Configuration.ValidationOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.Validation · configuration key IdentityServer:Validation
Checks applied to configured values, over and above whether they are configured.
Registration answers whether this server will send a browser somewhere. It does not answer whether the somewhere is a location at all, and the two are not the same question: a client-registration API, an administration screen or a SAML metadata document can put a URI into a store whose scheme runs script rather than navigating. This group is where that second question lives.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.Validation.InvalidRedirectUriPrefixes |
IdentityServer:Validation:InvalidRedirectUriPrefixes |
ICollection<string> |
[ "javascript:", "data:", "vbscript:", "file:", "blob:", "about:", "view-source:" ] |
URI prefixes this server refuses to send a browser to, however the URI was registered. Matched case-insensitively against a normalised form of the URI. A deny list rather than a list of permitted schemes, and the reason is native clients: a mobile application registers com.example.app:/callback and has every right to, so an allow list of http and https would refuse a legitimate registration in order to catch a hostile one. What the defaults have in common is that a browser asked to navigate to them either executes something (javascript:) or supplies its own document, and its own origin, rather than fetching one.The list is settable, so a deployment that has a use for one of these can drop it, and one that knows its clients are all web applications can add to it. |
PersistentGrantOptions
Fdyay.IdentityServer.Configuration.PersistentGrantOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.PersistentGrants · configuration key IdentityServer:PersistentGrants
What this server does with the grants it persists.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.PersistentGrants.DataProtectData |
IdentityServer:PersistentGrants:DataProtectData |
bool |
true |
Whether a persisted grant's Data is protected with the host's data protection ring before it is stored. On by default.What is in that column is why the default is on. A grant's Data is the serialized thing itself: for a refresh token or an authorization code, the whole claim set the subject was issued — every claim a profile service added included. Until 0.64.0 four stores wrote it as plaintext JSON, so the grant table held, in the clear, the full identity of everybody with a live session. The signing keys in that same database have been protected since key management shipped.Turning it off does not make old rows unreadable, and neither does turning it on. This option governs writes only. A read always tries to unprotect and falls back to treating the value as plaintext, so a store holding both shapes at once — the ordinary state during an upgrade — reads correctly either way. Off is a real choice, not a legacy setting. A host that keeps its grant store encrypted at rest by other means, or one that needs to read the column with a query rather than through this server, is not getting less protection by turning this off — it is getting the protection somewhere else. What it must not do is assume the column is unreadable while this is off. |
IdentityServerOptions.PersistentGrants.DeleteOneTimeOnlyRefreshTokensOnUse |
IdentityServer:PersistentGrants:DeleteOneTimeOnlyRefreshTokensOnUse |
bool |
false |
Whether a OneTimeOnly refresh token is deleted when it is used, rather than kept as consumed. Off by default. Duende's, whose default is on.On gives up replay detection. A consumed token presented again is the one sign that a handle was copied, and this server revokes the lineage when it sees one (RFC 9700 §4.14.2); a deleted token presented again is only unknown, refused without revoking anything, so the copy's successor lives on. Hence off here, where Duende's is on. On is for a host whose grant store must not keep used tokens until they expire. |
IdentityServerOptions.PersistentGrants.ConsumedRefreshTokenGracePeriod |
IdentityServer:PersistentGrants:ConsumedRefreshTokenGracePeriod |
TimeSpan |
00:00:00 |
How long after a OneTimeOnly refresh token is consumed it is still accepted if presented again. Zero — no grace, as in Duende's — by default. Ours: Duende's has no option, only the AcceptConsumedTokenAsync hook this sets.It widens the replay window by exactly this much. A consumed token presented within it is redeemed again — a fresh access token and a fresh refresh token, forking the lineage — and is not seen as a replay, so a copied handle used within it goes unnoticed. Measured from the first consumption, so presenting the token again does not extend it; after it a consumed token is a replay as before, refused, and its whole lineage revoked, forks included. Everything else is checked as for an unconsumed token. It is for a client that races itself — two instances of a BFF refreshing with one token, or a request carrying the old one just after a refresh landed — and is kept as short as that race. Has no effect with PersistentGrantOptions.DeleteOneTimeOnlyRefreshTokensOnUse, which leaves nothing to accept. Negative is a configuration error: UseIdentityServer refuses it. |
AuthenticationOptions
Fdyay.IdentityServer.Configuration.AuthenticationOptions in Fdyay.IdentityServer.Core · at IdentityServerOptions.Authentication · configuration key IdentityServer:Authentication
The session cookie's policy, and the cookies this server writes itself.
The session cookie's lifetime, sliding expiration and SameSite mode are Duende's options here since 0.101.0, at Duende's defaults, read where Duende reads them: when the session cookie's CookieAuthenticationOptions are configured, and — sliding — when a client's token slides a server-side session. Until then they were declined as a second source of truth for values ASP.NET Core owns; parity took them. What made the refusal reasonable still holds: they are applied as configuration, so a host that sets the scheme's own options after AddIdentityServer() still wins, and a test still says so.
The check-session cookie is the other case. SessionStateService writes it with Response.Cookies.Append, so no options system reaches it at all, and its name was a constant read at four sites — one of them inside the JavaScript the check-session iframe runs. Two identity servers on one registrable domain wrote the same cookie and each saw the other's browser state.
Its SameSite mode is deliberately not here, and the reason is a limitation worth stating rather than a knob worth adding. The cookie is written SameSite=None with Secure, because the iframe runs in the relying party's page and reads it from a third-party context. Over plain HTTP the browser drops it whatever SameSite says — so an option here would not make check-session work in an HTTP development setup; it would take relaxing Secure as well, on a cookie, which is not a setting this server is going to offer. Check-session does not work over plain HTTP, and that is the honest sentence. A single option would have read like a fix for it.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
IdentityServerOptions.Authentication.CheckSessionCookieName |
IdentityServer:Authentication:CheckSessionCookieName |
string |
"idsrv.session" |
The name of the cookie the check-session iframe reads. Defaults to idsrv.session.Read by the service that writes the cookie and substituted into the script that reads it. Those are the two halves, and honouring one without the other would leave an iframe polling a cookie name nothing writes — a session that never appears to change, which a relying party cannot tell apart from a session that is simply still valid. |
IdentityServerOptions.Authentication.CheckSessionCookieDomain |
IdentityServer:Authentication:CheckSessionCookieDomain |
string? |
null |
The domain to scope the check-session cookie to, or null to leave it host-only. Null rather than a computed value: host-only is the narrower default, and a host that needs the iframe reachable from a sibling subdomain is making a deliberate widening it should have to write down. |
IdentityServerOptions.Authentication.CoordinateClientLifetimesWithUserSession |
IdentityServer:Authentication:CoordinateClientLifetimesWithUserSession |
bool |
false |
Whether every client's tokens live only as long as the user's session here, unless the client says otherwise with Client.CoordinateLifetimeWithUserSession. Defaults to false, as in Duende. |
IdentityServerOptions.Authentication.CookieLifetime |
IdentityServer:Authentication:CookieLifetime |
TimeSpan |
10:00:00 |
How long the session cookie lasts. Defaults to 10 hours, as in Duende. |
IdentityServerOptions.Authentication.CookieSlidingExpiration |
IdentityServer:Authentication:CookieSlidingExpiration |
bool |
false |
Whether the session cookie's expiry moves with use. Defaults to false, as in Duende: a session ends AuthenticationOptions.CookieLifetime after sign-in however active it was.Also what lets a coordinating client's token renew the cookie's own ticket when it slides a server-side session; without it only the session's row slides. |
IdentityServerOptions.Authentication.CookieSameSiteMode |
IdentityServer:Authentication:CookieSameSiteMode |
SameSiteMode |
None |
The SameSite mode of the session cookie and the external sign-in cookie. Defaults to SameSiteMode.None, as in Duende, which sends them on cross-site requests and so needs HTTPS. |
IdentityServerOptions.Authentication.RequireCspFrameSrcForSignout |
IdentityServer:Authentication:RequireCspFrameSrcForSignout |
bool |
true |
Whether the signed-out page, which loads each client's front-channel logout URL in an iframe, carries a Content-Security-Policy whose frame-src names those clients' origins. On by default, as in Duende.Duende 8.0.1's, measured: when off, that page carries no policy at all. When on — and until 0.106.0 there was no choice — the page has this library's interactive-page policy; until 0.106.0 that policy had no frame-src, so default-src 'none' blocked every one of the page's iframes in a browser. |
IdentityServerOptions.Authentication.RequireAuthenticatedUserForSignOutMessage |
IdentityServer:Authentication:RequireAuthenticatedUserForSignOutMessage |
bool |
false |
Whether an end-session request from a user with no session here has its parameters ignored — id_token_hint, post_logout_redirect_uri and state. Off by default, as in Duende. |
IdentityServerOptions.Authentication.CookieAuthenticationScheme |
IdentityServer:Authentication:CookieAuthenticationScheme |
string? |
null |
The cookie scheme that holds a user's session here. When not set, the host's default authenticate scheme — and when there is none, IdentityServerConstants.DefaultCookieAuthenticationScheme if it is registered.Duende 8.0.1's, measured: what a host sets when its default authentication scheme is a policy scheme, or its own cookie, so this server reads, writes and ends the session where the host's sign-in put it. A scheme named here that is not registered is refused at startup. Since 0.107.0; until then idsrv was hard-coded at about fifteen sites, a few of which consulted the default scheme first and the rest did not. |
DynamicProviderOptions
Fdyay.IdentityServer.Configuration.DynamicProviderOptions in Fdyay.IdentityServer.AspNetCore · configured with AddDynamicProviders · configuration key DynamicProvider
How dynamic providers are served, and which kinds this host has registered.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
DynamicProviderOptions.PathPrefix |
DynamicProvider:PathPrefix |
PathString |
"/federation" |
Where a dynamic provider's callbacks live. Defaults to /federation.A dynamic scheme cannot share a callback path with any other, so each gets one under this prefix — /federation/{scheme}/signin. Static registrations set their own and are untouched. |
DynamicProviderOptions.PathMatchingCallback |
code only | Func<HttpContext, Task<string?>>? |
null |
Names the dynamic scheme a request is a callback for, or null when it is for none. When set, it is asked instead of DynamicProviderOptions.PathPrefix. Duende 8.0.1's, measured.For a host whose dynamic providers call back somewhere other than {PathPrefix}/{scheme}/… — a path per tenant, say. The callback paths a handler answers are its own options; this only says which scheme's handler a request is handed to. |
DynamicProviderOptions.SignInScheme |
DynamicProvider:SignInScheme |
string |
"idsrv.external" |
The scheme a dynamic provider signs the user in to: the external cookie. Duende's default. |
DynamicProviderOptions.SignOutScheme |
DynamicProvider:SignOutScheme |
string? |
"idsrv" |
The scheme a dynamic provider signs out of when its upstream says the session ended: this server's session cookie, which is also what it reads as when unset. Duende's default. |
LocalApiAuthenticationOptions
Fdyay.IdentityServer.Hosting.LocalApiAuthenticationOptions in Fdyay.IdentityServer.AspNetCore · configured with AddLocalApi, AddLocalApiAuthentication · configuration key LocalApiAuthentication
What the local API handler gives a host a say over.
Deliberately small. A local API is an API this server hosts itself, so almost everything a general-purpose JWT handler makes configurable — the authority, the signing keys, the issuer, the clock skew — is already settled by the server the handler is running inside, and offering it twice invites the two to disagree.
It derives from AuthenticationSchemeOptions (Microsoft.AspNetCore.Authentication), whose settings are that framework's and are not listed here.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
LocalApiAuthenticationOptions.ExpectedScope |
LocalApiAuthentication:ExpectedScope |
string |
"IdentityServerApi" |
The scope a token has to carry. Defaults to IdentityServerApi.Required, and there is no way to say "any token this server issued". That would be a door opened by every token in the deployment — including one minted for an unrelated API, by a client the host never meant to let near its administration surface. A host that genuinely wants it can write four lines of its own handler; it will not get it here by leaving a property empty. |
LocalApiAuthenticationOptions.SaveToken |
LocalApiAuthentication:SaveToken |
bool |
true |
Whether the token is kept so the API can read it back. Defaults to true. On by default because a local API calling on to something else is the ordinary case, and a token it cannot reach is a token it will be handed a second way instead. Read it back by naming this scheme: HttpContext.GetTokenAsync(IdentityServerConstants.LocalApi.AuthenticationScheme, "access_token"). The overload without a scheme reads the default authenticate scheme, which in any host that also serves this server's own pages is a browser cookie holding no access token — so it answers null, and it answers null in exactly the deployment this option exists for. |
LocalApiAuthenticationOptions.TokenMode |
LocalApiAuthentication:TokenMode |
LocalApiTokenMode |
DPoPAndBearer |
Which schemes a token is taken under. Defaults to LocalApiTokenMode.DPoPAndBearer.Duende's defaults to LocalApiTokenMode.BearerOnly. This handler has taken a token under either scheme since 0.45.0, so its default stays both: a default of Bearer only would turn away every caller holding a token bound to its key. Whatever the mode, a token bound to a key is refused under Bearer — the mode decides which schemes are read, never whether a binding is held to. |
LocalApiAuthenticationOptions.Events |
LocalApiAuthentication:Events |
LocalApiAuthenticationEvents |
see LocalApiAuthenticationEvents | The host's hook for shaping the principal the API sees. |
LocalApiAuthenticationEvents
Fdyay.IdentityServer.Hosting.LocalApiAuthenticationEvents in Fdyay.IdentityServer.AspNetCore · at LocalApiAuthenticationOptions.Events · configuration key LocalApiAuthentication:Events
Host hooks on the local API handler.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
LocalApiAuthenticationOptions.Events.OnClaimsTransformation |
code only | Func<LocalApiClaimsTransformationContext, Task> |
a default handler | Runs after a token is accepted and before the API is reached. A shaping hook, not a second gate: by the time it runs the token has been validated, its binding checked and its scope required, and replacing the principal here cannot undo any of that. A host that wants to refuse a caller refuses it in authorization, where a refusal is visible as one. |
SamlAuthenticationOptions
Fdyay.IdentityServer.Saml.Sp.SamlAuthenticationOptions in Fdyay.IdentityServer.Saml · configured with services.Configure<SamlAuthenticationOptions>(…) · configuration key SamlAuthentication
A stored SAML provider's settings a host can override, per scheme, in code.
Duende 8.0.1's SamlAuthenticationOptions, measured: named options for each saml scheme, filled from the stored row and DynamicProviderOptions first, so a host's services.Configure<SamlAuthenticationOptions>(scheme, …) or PostConfigure sees those values and replaces the ones it names. What it settles wins over the row; what it leaves null falls back to the row.
An AuthenticationSchemeOptions because Duende's is, and because that is what lets the same mechanism that fills a handler's options from a row fill these.
It derives from AuthenticationSchemeOptions (Microsoft.AspNetCore.Authentication), whose settings are that framework's and are not listed here.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
SamlAuthenticationOptions.SpEntityId |
SamlAuthentication:SpEntityId |
string? |
null |
The entity id this server presents. Null falls back to the row's, then to this server's issuer. |
SamlAuthenticationOptions.OutboundSigningAlgorithm |
SamlAuthentication:OutboundSigningAlgorithm |
string? |
null |
The signature method this server signs its messages to the provider with. |
SamlAuthenticationOptions.WantAssertionsSigned |
SamlAuthentication:WantAssertionsSigned |
bool? |
null |
Whether this server asks for signed assertions. Carried for Duende's shape, and not able to turn the requirement off: this server's service provider refuses an unsigned assertion whatever this says, and its metadata says WantAssertionsSigned="true" because that is what it does. A scheme configured to ask for less is logged as a warning when its options are built. |
SamlAuthenticationOptions.SignInScheme |
SamlAuthentication:SignInScheme |
string? |
null |
The cookie a signed-in user lands in. Null falls back to DynamicProviderOptions.SignInScheme. |
SamlAuthenticationOptions.SignOutScheme |
SamlAuthentication:SignOutScheme |
string? |
null |
The session an inbound LogoutRequest ends. Null falls back to DynamicProviderOptions.SignOutScheme. |
SamlOptions
Fdyay.IdentityServer.Saml.Configuration.SamlOptions in Fdyay.IdentityServer.Saml · configured with AddSaml · configuration key Saml
Options for the native SAML implementation.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
SamlOptions.EntityId |
Saml:EntityId |
string? |
null |
The IdP entity ID advertised in metadata and assertions. Defaults to the issuer when null. |
SamlOptions.SigningCertificate |
code only | X509Certificate2? |
null |
A certificate to sign with instead of this server's key material. Null (the default) signs with the server's current signing key, as Duende's does. Read by the default ISamlSigningService: when set, it signs every assertion, response and logout message and is the one key metadata publishes, and key rotation does not reach SAML. Null, the signing key is the one IKeyMaterialService signs tokens with — an RSA key wrapped in a certificate of its own — so it rotates with them. Duende has no such option; it is kept for a host whose partners pinned a certificate. Until 0.144.0 it was required. |
SamlOptions.Metadata |
Saml:Metadata |
SamlMetadataOptions |
see SamlMetadataOptions | The cacheDuration and validUntil published metadata carries. Duende's Metadata. |
SamlOptions.ClockSkew |
Saml:ClockSkew |
TimeSpan |
00:05:00 |
Tolerance applied when checking assertion time conditions. Defaults to 5 minutes. |
SamlOptions.EnableIdpInitiatedSignOn |
Saml:EnableIdpInitiatedSignOn |
bool |
false |
Whether this server will start a sign-on no service provider asked for. Defaults to false. The IdP-initiated half of the Web SSO profile (§4.1.5): a link in this server's own portal that posts an assertion to a registered service provider. It is a capability rather than a default because the request that starts it carries no message this server can authenticate — that is what "unsolicited" means — so the decision to expose a route that signs a user into a service provider on a GET belongs to the host. Read by saml/sso/initiate since 0.59.0, which answers nothing until it is set. Documented until 0.178.0 as inert, a note from the commit that declared it which outlived the commit that read it. |
SamlOptions.AssertionLifetime |
Saml:AssertionLifetime |
TimeSpan |
00:05:00 |
How long an issued assertion remains valid. Defaults to 5 minutes. |
SamlOptions.DefaultSigningBehavior |
Saml:DefaultSigningBehavior |
SamlSigningBehavior |
SignAssertion |
What is signed in a response to a provider that does not say; defaults to the assertion, as Duende's does. |
SamlOptions.RequireHttpsServiceProviderUrls |
Saml:RequireHttpsServiceProviderUrls |
bool |
true |
Whether a registered service provider's reply and logout addresses must be https. Defaults to true.A SAML response carries a signed assertion, which is a bearer credential for whoever holds it, and the registration is the only thing that decides where it is delivered. Plaintext to a host that is not loopback puts that credential on a wire, so as of 0.71.0 such a registration is refused where it is read rather than served. Loopback is exempt whatever this says, because a partner on the developer's own machine is the case https cannot be asked of, and a credential that never leaves the host is not on a wire. Setting this to false is the escape for a deployment terminating TLS somewhere this server cannot see — it is a statement that the plaintext hop is inside a boundary, not that the hop does not exist. |
SamlOptions.WantAuthnRequestsSigned |
Saml:WantAuthnRequestsSigned |
bool |
true |
Whether an AuthnRequest must be signed. Defaults to true, as Duende's does. Duende 8.0.1's SamlOptions.WantAuthnRequestsSigned, measured: advertised in metadata as the IdP descriptor's WantAuthnRequestsSigned, and enforced for every service provider that does not say otherwise with SamlServiceProvider.RequireSignedAuthnRequests. A provider with no SamlServiceProvider.RequestSigningCertificate cannot sign, so it is refused unless it opts out. |
SamlOptions.RequireSignedLogoutResponses |
Saml:RequireSignedLogoutResponses |
bool |
true |
Whether a LogoutResponse must be signed. Defaults to true, as Duende's does. Duende 8.0.1's SamlOptions.RequireSignedLogoutResponses, measured: read at the single logout endpoint for a LogoutResponse only, for every service provider that does not say otherwise with SamlServiceProvider.RequireSignedLogoutResponses. False lets an unsigned answer through; one that carries a signature is still held to it. Until 0.154.0 every LogoutResponse had to be signed, as it still must by default. |
SamlOptions.MatchLogoutRequestToSession |
Saml:MatchLogoutRequestToSession |
bool |
false |
Whether a verified LogoutRequest must name a SAML session this browser holds with the provider before it ends the session. Defaults to false: such a request ends the session, as it always has. True runs Duende 8.0.1's LogoutRequestValidator.ValidateSessionAsync checks, measured, for every service provider that does not say otherwise with SamlServiceProvider.MatchLogoutRequestToSession. For a signed-in user, a request with no NameID, or whose NameID matches none of the provider's sessions here, is refused; one from a provider with no session here, or whose SessionIndex names none, is answered Success and ends nothing. Duende always runs them; Ours: off by default (decided 2026-10-14), because each changes what this server does with a verified request. New in 0.159.0. |
SamlOptions.DefaultRequestMaxAge |
Saml:DefaultRequestMaxAge |
TimeSpan |
00:05:00 |
How old an AuthnRequest's IssueInstant may be. Defaults to 5 minutes, as Duende's does.Since 0.178.0 also how old a LogoutRequest may be when it reaches this server's service provider (SamlSpHandler), with SamlSpOptions.ClockSkew added there. |
SamlOptions.MaxMessageSize |
Saml:MaxMessageSize |
int |
1048576 |
The longest inbound SAML message, in characters once decoded. Defaults to 1 MiB, as Duende's does. Checked before a POST-bound message is decoded and while a redirect-bound one is inflated, so a few kilobytes of deflated input cannot be made to expand without end, and again when the XML is loaded. Since 0.178.0 at this server's service provider too — the SAMLResponse its assertion consumer reads and the LogoutRequest its single logout endpoint reads, and in SamlResponseValidator — where until then neither was bounded. Duende 8.0.1's service provider bounds neither, measured. |
SamlOptions.MaxRelayStateLength |
Saml:MaxRelayStateLength |
int |
80 |
The longest RelayState accepted, in UTF-8 bytes. Defaults to 80, the limit SAML Bindings §3.4.3 sets. |
SamlOptions.SupportedNameIdFormats |
Saml:SupportedNameIdFormats |
ICollection<string> |
[ "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" ] |
The NameID formats a request may ask for, and metadata advertises, in this order. Defaults to emailAddress and unspecified, as Duende's does.A request naming a format not listed here — or, naming none, from a provider whose SamlServiceProvider.DefaultNameIdFormat is not listed — is refused with InvalidNameIDPolicy. The default ISamlNameIdGenerator issues emailAddress from SamlOptions.EmailNameIdClaimType and every other format from sub, so listing persistent or transient labels the subject id with that format, as Duende's does; a different value is a generator of the host's own. |
SamlOptions.EmailNameIdClaimType |
Saml:EmailNameIdClaimType |
string |
"email" |
The claim an emailAddress NameID is read from. Defaults to email, as Duende's does. |
SamlOptions.DefaultAuthnContextMappings |
Saml:DefaultAuthnContextMappings |
IReadOnlyDictionary<string, string> |
{ "pwd": "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport", "external": "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified" } |
The acr and amr values and the AuthnContextClassRef each is issued as, for a provider with no mappings of its own. Defaults to Duende's two: pwd as PasswordProtectedTransport, external as unspecified.The signed-in user's acr is looked up first, then each amr in the order the claims are held; the first found is issued, and unspecified when none is. Until 0.134.0 every assertion said PasswordProtectedTransport, however the user had signed in. |
SamlOptions.DefaultClaimMappings |
Saml:DefaultClaimMappings |
IReadOnlyDictionary<string, string> |
{ "name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "role": "http://schemas.xmlsoap.org/ws/2005/05/identity/role" } |
The claim types and the attribute name each is issued as, for a provider with no mappings of its own. Defaults to Duende's three: name, email and role as the WS-Federation claim URIs.A claim type not listed is issued under its own name. role maps to http://schemas.xmlsoap.org/ws/2005/05/identity/role — without the claims/ segment the other two have — because that is the value Duende 8.0.1 ships. Until 0.141.0 the attributes were the session's name and email claims under those names. |
SamlOptions.Endpoints |
Saml:Endpoints |
SamlEndpointOptions |
see SamlEndpointOptions | Where the SAML endpoints are served, and over which bindings. Duende's SamlOptions.Endpoints. |
SamlOptions.SigninStateLifetime |
Saml:SigninStateLifetime |
TimeSpan |
00:15:00 |
How long a sign-on waits for its user at the login page before the request it arrived with is dropped. Defaults to 15 minutes, as Duende's SigninStateLifetime does.Written onto each SamlSignInState as its ExpiresAt when it is stored, so a store of the host's own can expire it without knowing these options, as Duende writes its ExpiresAtUtc. Until 0.145.0 the in-memory store kept every state for twenty minutes, and a store of the host's own was told nothing. |
SamlOptions.LogoutSessionLifetime |
Saml:LogoutSessionLifetime |
TimeSpan |
00:05:00 |
How long a single logout sequence may take before it is dropped. Defaults to 5 minutes, as Duende's LogoutSessionLifetime does.Written onto each SamlLogoutSession as its ExpiresAt, for the same reason. Until 0.145.0 the in-memory store kept every sequence for a fixed five minutes. |
SamlOptions.AuthnRequestErrorInspector |
code only | Action<ReadErrorInspectorContext<SamlAuthnRequest>>? |
null |
Called when an inbound AuthnRequest does not read cleanly, with every error found; null (the default) refuses it as before. Duende's AuthnRequestErrorInspector.The inspector may remove an error, or set its Error.Ignore, and the request is then read and validated as any other; it may also set a corrected request as ReadErrorInspectorContext.Data — a date in a partner's quirky format, say. Called only when there is an error, and at each read of the request (the sign-on, its resumption, the login page's context). Data.Issuer is unverified when it is called, as Duende warns: no decision should rest on it alone.It cannot make a message trusted. The signature is checked after the inspector returns, over the message as received and against the provider the request finally names, and every check the validator makes is still made. In Duende's the signature is verified while reading, before the inspector runs, against the issuer as sent, and the request's TrustLevel is a settable property of the data the inspector is handed. |
SamlOptions.LogoutRequestErrorInspector |
code only | Action<ReadErrorInspectorContext<SamlLogoutRequest>>? |
null |
Called when an inbound LogoutRequest does not read cleanly; null (the default) refuses it as before. Duende's LogoutRequestErrorInspector, as SamlOptions.AuthnRequestErrorInspector is for an AuthnRequest. |
SamlOptions.LogoutResponseErrorInspector |
code only | Action<ReadErrorInspectorContext<SamlLogoutResponse>>? |
null |
Called when an inbound LogoutResponse does not read cleanly; null (the default) refuses it as before. Duende's LogoutResponseErrorInspector, as SamlOptions.AuthnRequestErrorInspector is for an AuthnRequest. |
SamlMetadataOptions
Fdyay.IdentityServer.Saml.Configuration.SamlMetadataOptions in Fdyay.IdentityServer.Saml · at SamlOptions.Metadata · configuration key Saml:Metadata
How long a partner may keep this identity provider's metadata. Duende's SamlMetadataOptions.
Written on the published EntityDescriptor as cacheDuration and validUntil (SAML Metadata §2.3.1): how often a partner should fetch it again, and the moment it stops being usable at all. The signing key published there rotates with this server's key material, so a partner that refreshes within SamlMetadataOptions.CacheDuration learns a new key before it signs. As of 0.144.0; until then the metadata said neither.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
SamlOptions.Metadata.CacheDuration |
Saml:Metadata:CacheDuration |
TimeSpan |
12:00:00 |
How long a partner may cache the metadata before fetching it again. Defaults to 12 hours, as Duende's does. |
SamlOptions.Metadata.ExpiryDuration |
Saml:Metadata:ExpiryDuration |
TimeSpan |
5.00:00:00 |
How long after it is served the metadata expires. Defaults to 5 days, as Duende's does. |
SamlEndpointOptions
Fdyay.IdentityServer.Saml.Configuration.SamlEndpointOptions in Fdyay.IdentityServer.Saml · at SamlOptions.Endpoints · configuration key Saml:Endpoints
Where the SAML endpoints are served, and over which bindings. Duende 8.0.1's SamlEndpointOptions, measured.
Read per request, wherever a path is needed — the router, the return URL, the Destination an inbound message must name, and the metadata — so one setting moves all of them at once, whether it is made in AddSaml's callback or in a Configure<SamlOptions> after it. Duende reads its paths once, from AddSaml's callback, to register its routes.
The paths keep this server's defaults rather than Duende's /Saml2/SSO and /Saml2/SLO: they are published in metadata and configured at every partner, so moving them is the host's decision to make, not an upgrade's.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
SamlOptions.Endpoints.SingleSignOnServicePath |
Saml:Endpoints:SingleSignOnServicePath |
string |
"/saml/sso" |
The single sign-on service's path. Defaults to /saml/sso.The IdP-initiated door is served beneath it, at {path}/initiate. |
SamlOptions.Endpoints.SingleSignOnServiceBindings |
Saml:Endpoints:SingleSignOnServiceBindings |
ICollection<string> |
[ "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" ] |
The bindings the single sign-on service accepts and metadata advertises. Defaults to HTTP-Redirect and HTTP-POST, as Duende's does; empty switches the service off. |
SamlOptions.Endpoints.SingleSignOnCallbackPath |
Saml:Endpoints:SingleSignOnCallbackPath |
string |
"/saml/sso/callback" |
Where the browser comes back from the login page to have its sign-on answered. Defaults to /saml/sso/callback. |
SamlOptions.Endpoints.SingleLogoutServicePath |
Saml:Endpoints:SingleLogoutServicePath |
string |
"/saml/slo" |
The single logout service's path. Defaults to /saml/slo. |
SamlOptions.Endpoints.SingleLogoutServiceBindings |
Saml:Endpoints:SingleLogoutServiceBindings |
ICollection<string> |
[ "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" ] |
The bindings the single logout service accepts and metadata advertises. Defaults to HTTP-Redirect and HTTP-POST, as Duende's does; empty switches the service off. |
SamlOptions.Endpoints.StateIdParameterName |
Saml:Endpoints:StateIdParameterName |
string |
"samlStateId" |
The query parameter the return URL carries the stored sign-in's reference in. Defaults to samlStateId, as Duende's does. |
SamlSpOptions
Fdyay.IdentityServer.Saml.Sp.SamlSpOptions in Fdyay.IdentityServer.Saml · configured with AddExternalSaml2, AddSaml2 · configuration key SamlSp
Options for acting as a SAML 2.0 service provider toward an upstream identity provider.
It derives from RemoteAuthenticationOptions (Microsoft.AspNetCore.Authentication), whose settings are that framework's and are not listed here.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
SamlSpOptions.SpEntityId |
SamlSp:SpEntityId |
string |
null |
Our entity ID as an SP (used as the AuthnRequest issuer and expected assertion audience). |
SamlSpOptions.IdpEntityId |
SamlSp:IdpEntityId |
string |
null |
The upstream IdP's entity ID (expected assertion issuer). |
SamlSpOptions.IdpSingleSignOnUrl |
SamlSp:IdpSingleSignOnUrl |
string |
null |
The upstream IdP's Single Sign-On URL (HTTP-Redirect binding). |
SamlSpOptions.IdpSingleLogoutUrl |
SamlSp:IdpSingleLogoutUrl |
string? |
null |
The upstream IdP's Single Logout URL (HTTP-Redirect binding). Required to initiate SP logout. |
SamlSpOptions.IdpSingleSignOnBinding |
SamlSp:IdpSingleSignOnBinding |
string |
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" |
How the AuthnRequest reaches the upstream IdP's Single Sign-On URL: HTTP-Redirect (the default) or HTTP-POST, as Bindings names them.Duende 8.0.1's service provider binds its request either way (its SamlProvider.BindingType). A posted request is signed inside the XML rather than beside it, and arrives as a form the browser submits. Since 0.109.0. |
SamlSpOptions.OutboundSigningAlgorithm |
SamlSp:OutboundSigningAlgorithm |
string? |
null |
The signature method this service provider signs with, as a URI. Null — the default — follows the key: RSA-SHA256, or ECDSA with the hash its curve pairs with. Duende 8.0.1's OutboundSigningAlgorithm, read for every message it signs: the AuthnRequest, the LogoutRequest and the LogoutResponse. It has to be a method this server accepts — SHA-256, SHA-384 or SHA-512, RSA or ECDSA to match SamlSpOptions.SigningCertificate's key — so SHA-1, which Duende can still be told to use, is refused at startup here. Since 0.109.0. |
SamlSpOptions.SignOutScheme |
SamlSp:SignOutScheme |
string? |
null |
The scheme whose session an inbound LogoutRequest ends. Defaults to the sign-in scheme.The same shape OpenIdConnectOptions has, and for the same reason: the scheme an external identity is written to is not the scheme that holds the session. When the identity provider ends the session at its end and tells us, what has to go is the local session — and dropping that cookie is what makes the rest of the sign-out sequence run, since 0.43.0 wraps the handler that holds it. Left null it falls back to RemoteAuthenticationOptions.SignInScheme, which is the honest default for a handler registered outside an identity server: there is no other session it knows of. |
SamlSpOptions.SignedOutCallbackPath |
SamlSp:SignedOutCallbackPath |
PathString |
"/signout-saml" |
The path the IdP posts the LogoutResponse back to. Defaults to /signout-saml. |
SamlSpOptions.IdpSigningCertificate |
code only | X509Certificate2 |
null |
The upstream IdP's signing certificate, used to verify assertions. |
SamlSpOptions.MetadataPath |
SamlSp:MetadataPath |
PathString |
"/saml-metadata" |
Where this service provider publishes its metadata. Defaults to /saml-metadata.Public information by definition — an entity id, a reply address, and the certificate a partner encrypts to. Set it to PathString.Empty to publish nothing, at the cost of handing the same values over by some other route. |
SamlSpOptions.SigningCertificate |
code only | X509Certificate2? |
null |
Our certificate for signing the messages we send. Null to send them unsigned. Needs the private key. A partner identity provider that requires signed requests refuses an unsigned one, and until 0.70.0 there was no key here to sign with — so the three messages this handler sends all went out unsigned and the metadata said so. All three, which is the part worth stating: the AuthnRequest that starts a sign-on, the LogoutRequest that starts a logout, and the LogoutResponse that answers the provider's. Signing the two requests and not the response would satisfy a partner's AuthnRequestsSigned and still fail it at the end of a logout, which is the harder failure to attribute.Setting it changes what the published metadata claims, because the two cannot honestly disagree: the descriptor's AuthnRequestsSigned follows this, and the certificate is published as a signing KeyDescriptor. Claiming to sign without publishing the key leaves a partner told to expect a signature it has no way to verify.The messages travel on the HTTP-Redirect binding, so the signature is the detached one on the query string (Bindings §3.4.4.1) rather than an enveloped XML signature — a DEFLATEd message in a URL has nowhere to carry one. |
SamlSpOptions.DecryptionCertificate |
code only | X509Certificate2? |
null |
Our certificate for decrypting an EncryptedAssertion. Null when we publish no encryption key.Needs the private key: a partner IdP encrypts the content key to the public half. |
SamlSpOptions.AllowIdpInitiatedSignOn |
SamlSp:AllowIdpInitiatedSignOn |
bool |
false |
Whether an assertion arriving for a request this server never made is accepted. Defaults to false. Off, because the correlation this gives up is doing real work: a solicited response is tied to state this handler protected into RelayState when it sent the request, which is what says this browser started this sign-on. An unsolicited assertion has none of that, so accepting one is a decision about a partner IdP that a host makes deliberately.Accepting them never means ignoring InResponseTo. An unsolicited response must name no request at all; one that names a request, arriving with no state, is a solicited response somebody captured.The sign-in is recorded against this scheme — the scheme item the external sign-in page reads — so the provider's subject is looked up among this provider's users and no other's, whatever the assertion's attributes say. Each assertion is accepted once (SAML Profiles §4.1.4.5). Both since 0.178.0: until then an unsolicited sign-in recorded no scheme, and the page took the provider from the identity's own idp claim, which an attribute could supply. Read since 0.59.0; documented until 0.178.0 as inert, which it was not. |
SamlSpOptions.IdpInitiatedReturnPath |
SamlSp:IdpInitiatedReturnPath |
PathString |
"/" |
Where the browser lands after an unsolicited sign-on. Defaults to /.There is no return URL to honour: nothing on this site asked for the sign-on, so there is nowhere it was going. The IdP's RelayState is not that destination either — it is a value the partner chose, and navigating to it would make this a redirector for anyone who can reach the reply address.The browser lands here with the identity in the external cookie; with the shipped pages it is the external sign-in callback ( /Account/ExternalLogin?handler=Callback) that turns it into a session. Read since 0.59.0; documented until 0.178.0 as inert, which it was not. |
SamlSpOptions.RequireEncryptedAssertion |
SamlSp:RequireEncryptedAssertion |
bool |
false |
Whether an assertion that arrives unencrypted is refused. Defaults to false. Set it once the partner IdP is known to encrypt. Accepting either shape until then is the common case; accepting either shape afterwards lets whoever is on the path strip the encryption. |
SamlSpOptions.NameIdClaimType |
SamlSp:NameIdClaimType |
string |
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" |
An additional claim type the SAML NameID is mapped to. Defaults to ClaimTypes.NameIdentifier, which the external identity carries either way.The NameID always arrives as ClaimTypes.NameIdentifier, because that is the type the shipped external-login page reads to find the provider subject and the type the sign-out path reads off the local principal to name the user back to the identity provider. Setting this adds a second claim of the given type for a deployment whose own external-login handling reads something else.It used to replace the canonical type, which made every value but the default a registration that broke sign-in outright and sent a LogoutRequest naming nobody. Fixed in 0.52.0; a host that had set it and worked around the break needs no change, because the claim it asked for is still there. |
SamlSpOptions.ClockSkew |
SamlSp:ClockSkew |
TimeSpan |
00:05:00 |
Tolerance applied when checking assertion time conditions. Defaults to 5 minutes. Since 0.178.0 also an inbound LogoutRequest's: its NotOnOrAfter, and an IssueInstant neither further ahead than this nor older than SamlOptions.DefaultRequestMaxAge and this together. An assertion's and a logout request's ID is remembered until its own expiry plus this, which is when it would be refused anyway. |
SamlSpOptions.StateDataFormat |
code only | ISecureDataFormat<AuthenticationProperties> |
null |
Protects the relay state that correlates a response to its request. |
DapperStoreOptions
Fdyay.IdentityServer.Dapper.Configuration.DapperStoreOptions in Fdyay.IdentityServer.Dapper · configured with AddDapperStores · configuration key DapperStore
Options for the Dapper-backed stores.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
DapperStoreOptions.Provider |
DapperStore:Provider |
DatabaseProvider |
Sqlite |
The database provider. Defaults to SQLite. |
DapperStoreOptions.ConnectionString |
DapperStore:ConnectionString |
string |
"" |
The ADO.NET connection string. |
DapperStoreOptions.InitializeSchema |
DapperStore:InitializeSchema |
bool |
true |
Whether the schema is created on startup. Defaults to true. Set this to false where the schema is owned outside the application — a migration project or a DACPAC — so that the deployed schema stays the single source of truth and the application never writes DDL. |
DapperStoreOptions.Stores |
DapperStore:Stores |
DapperStores |
All |
Which stores to back with the database. Defaults to DapperStores.All. |
DapperStoreOptions.EnableTokenCleanup |
DapperStore:EnableTokenCleanup |
bool |
false |
Whether expired persisted grants are swept in the background. Defaults to false. Off by default because a host whose schema is managed elsewhere may not want the application issuing deletes. Leaving it off means something else has to prune the table — nothing else does it. |
DapperStoreOptions.TokenCleanupInterval |
DapperStore:TokenCleanupInterval |
TimeSpan |
01:00:00 |
How often the sweep runs. Defaults to one hour. |
DapperStoreOptions.RemoveConsumedTokens |
DapperStore:RemoveConsumedTokens |
bool |
false |
Whether consumed grants are removed as well as expired ones. Defaults to false. A consumed grant cannot be redeemed again, so keeping it only preserves the record that it was used. Turn this on where that record is not wanted and the table would otherwise keep every spent one. |
ClientCredentialsClient
Fdyay.AccessTokenManagement.ClientCredentialsClient in Fdyay.AccessTokenManagement · configured with AddClient · configuration key ClientCredentialsClient
A registered client-credentials client: where to ask for a token, and as whom.
| Property | Configuration key | Type | Default | Description |
|---|---|---|---|---|
ClientCredentialsClient.TokenEndpoint |
ClientCredentialsClient:TokenEndpoint |
Uri? |
null |
The authorization server's token endpoint. |
ClientCredentialsClient.ClientId |
code only | ClientId |
default |
The client_id sent with the token request. |
ClientCredentialsClient.ClientSecret |
code only | ClientSecret |
default |
The client_secret sent with the token request. |
ClientCredentialsClient.Scope |
code only | Scope? |
null |
The scope to request, or null to let the authorization server decide. |
ClientCredentialsClient.HttpClientName |
ClientCredentialsClient:HttpClientName |
string? |
null |
The named HttpClient the token request itself travels on.Not the client the token is later attached to — this one. It exists because the backchannel to the authorization server may need handling the application's outbound calls do not: a development certificate to trust, a proxy, a client certificate. |
ClientCredentialsClient.ExpirationSkew |
ClientCredentialsClient:ExpirationSkew |
TimeSpan |
00:01:00 |
How long before expiry a cached token stops being handed out. Defaults to one minute. A token that expires in flight is rejected by the resource server, and the caller sees a 401 it did nothing to deserve. The window has to cover the request's own travel time, so it is a margin rather than a precision setting. |
ClientCredentialsClient.TokenRequestTimeout |
ClientCredentialsClient:TokenRequestTimeout |
TimeSpan |
00:00:10 |
How long the token request itself may take before it is given up on. Ten seconds. The bound on how long an outbound hop may hang, and here it is also the bound on how long everything else waits. Token acquisition is single-flighted per client, so one caller makes the request and every other caller that missed the cache queues behind it — which turns a slow authorization server into a stalled application rather than one slow call. Without this the bound was HttpClient's own default of a hundred seconds, which is not a choice anybody made about a hop that exists to keep a fifteen-minute token fresh.Ten seconds because that is what the two sibling outbound hops already use — the back-channel logout notification, per relying party, and the JAR request_uri fetch — and for the same reason they give: somebody is waiting on the answer. This is the third of the three and the only one whose delay is shared by every concurrent caller.It bounds one request, so a caller that arrives while another holds the single-flight gate can wait up to twice it: once for the request in front of it, once for its own. A failing endpoint is worse than that, because a failure is deliberately not cached and each queued caller then tries in turn — so n waiting callers cost up to n times this value before the last of them hears about it. That is the gate's shape rather than this setting's, and it is recorded as its own work. |