Class IdentityServerOptions
- Namespace
- Fdyay.IdentityServer.Configuration
- Assembly
- Fdyay.IdentityServer.Core.dll
Top-level configuration for the identity server.
public class IdentityServerOptions
- Inheritance
-
IdentityServerOptions
- Inherited Members
Properties
AccessTokenJwtType
The value written to the typ header of JWT access tokens. Defaults to at+jwt, per RFC 9068.
public string AccessTokenJwtType { get; set; }
Property Value
Remarks
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.
Authentication
The cookies this server writes itself, rather than through a framework handler.
public AuthenticationOptions Authentication { get; set; }
Property Value
BackChannelLogout
Back-channel logout notification behaviour (OpenID Connect Back-Channel Logout 1.0).
public BackChannelLogoutOptions BackChannelLogout { get; set; }
Property Value
Ciba
Back-channel authentication behaviour (OpenID Connect CIBA Core 1.0).
public CibaOptions Ciba { get; set; }
Property Value
Cors
CORS settings for the protocol endpoints.
public CorsOptions Cors { get; set; }
Property Value
Csp
Content-Security-Policy for the pages and iframes this server serves.
public CspOptions Csp { get; set; }
Property Value
DPoP
Options for DPoP (RFC 9449).
public DPoPOptions DPoP { get; set; }
Property Value
DeviceFlow
Device authorization grant behaviour (RFC 8628).
public DeviceFlowOptions DeviceFlow { get; set; }
Property Value
Discovery
Discovery document options.
public DiscoveryOptions Discovery { get; set; }
Property Value
EmitIssuerIdentificationResponseParameter
Whether an authorization response carries the iss parameter (RFC 9207). Defaults to true.
public bool EmitIssuerIdentificationResponseParameter { get; set; }
Property Value
Remarks
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.
EmitScopesAsSpaceDelimitedStringInJwt
Whether a JWT access token carries scope as one space-delimited string. Defaults to true.
public bool EmitScopesAsSpaceDelimitedStringInJwt { get; set; }
Property Value
Remarks
RFC 9068 §2.2.3 says the claim on an at+jwt access token is "a JSON string containing a
space-separated list", and 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.
EmitStaticAudienceClaim
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.
public bool EmitStaticAudienceClaim { get; set; }
Property Value
Remarks
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.
Endpoints
Endpoint enablement flags.
public EndpointsOptions Endpoints { get; set; }
Property Value
Events
Which kinds of event reach the sink. All off by default.
public EventsOptions Events { get; set; }
Property Value
InputLengths
Bounds on the length of what a caller may send.
public InputLengthRestrictions InputLengths { get; set; }
Property Value
IssuerUri
The issuer name (URI). If null, it is inferred from the request origin.
public string? IssuerUri { get; set; }
Property Value
JwtValidationClockSkew
How far past its exp a JWT access token this server issued is still accepted. Defaults to
Zero.
public TimeSpan JwtValidationClockSkew { get; set; }
Property Value
Remarks
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.
KeyManagement
Key management options.
public KeyManagementOptions KeyManagement { get; set; }
Property Value
LogoutTokenJwtType
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.
public string LogoutTokenJwtType { get; set; }
Property Value
Remarks
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.
LowerCaseIssuerUri
Whether the lowercase issuer name is emitted. Defaults to true.
public bool LowerCaseIssuerUri { get; set; }
Property Value
MutualTls
Mutual-TLS client authentication and certificate-bound tokens (RFC 8705).
public MutualTlsOptions MutualTls { get; set; }
Property Value
PersistentGrants
What this server does with the grants it persists.
public PersistentGrantOptions PersistentGrants { get; set; }
Property Value
PushedAuthorization
Pushed authorization request behaviour (RFC 9126).
public PushedAuthorizationOptions PushedAuthorization { get; set; }
Property Value
StrictClientAssertionAudienceValidation
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.
public bool StrictClientAssertionAudienceValidation { get; set; }
Property Value
Remarks
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.
StrictJarValidation
Whether a request object must be typed oauth-authz-req+jwt (RFC 9101 §10.8). Defaults to false.
public bool StrictJarValidation { get; set; }
Property Value
Remarks
Duende's, measured from its 8.0.1 package. Not asked of a signed CIBA request, as Duende's CIBA validator does not.
SupportedClientAssertionSigningAlgorithms
The signing algorithms a client authentication assertion (RFC 7523) may use.
public ICollection<string> SupportedClientAssertionSigningAlgorithms { get; }
Property Value
Remarks
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.
SupportedRequestObjectSigningAlgorithms
The signing algorithms a request object (RFC 9101) may use.
public ICollection<string> SupportedRequestObjectSigningAlgorithms { get; }
Property Value
Remarks
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.
TokenRequestDefaultScopesFromResourceStore
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.
public bool TokenRequestDefaultScopesFromResourceStore { get; set; }
Property Value
Remarks
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.
UserInteraction
User interaction (login/consent) options.
public UserInteractionOptions UserInteraction { get; set; }
Property Value
ValidateTenantOnAuthorization
Whether a session whose tenant claim differs from the request's tenant: hint is sent back to sign
in. Defaults to false.
public bool ValidateTenantOnAuthorization { get; set; }
Property Value
Remarks
Duende's name, default and rule, measured from its ProcessLoginAsync.
Validation
Checks this server applies to values it has already accepted from a registration.
public ValidationOptions Validation { get; set; }