Table of Contents

Class SamlSignInState

Namespace
Fdyay.IdentityServer.Saml.Stores
Assembly
Fdyay.IdentityServer.Saml.dll

A validated sign-on request, kept while its user is away signing in.

public sealed class SamlSignInState
Inheritance
SamlSignInState
Inherited Members

Remarks

The endpoint used to re-encode the request into the return URL instead, which sent the validated message out through the browser and brought it back to be validated again from browser-supplied bytes. That cost a service provider its signature: a POST-bound request carries one inside the XML and a redirect-bound one carries it beside the message, so re-encoding a posted request as a redirect query drops what it was signed with. An SP registered with a request signing certificate that posted its request was refused on the return leg for a signature it had actually sent.

Keeping it here instead means the browser carries an opaque reference and nothing else, and the request the endpoint answers is the one it validated rather than one it was handed back.

Properties

Created

When the state was stored, so a store can drop what nobody came back for.

public required DateTimeOffset Created { get; init; }

Property Value

DateTimeOffset

DenialError

The user's denial of this sign-in, when the login page recorded one: answered to the service provider. Duende's.

public InteractionError? DenialError { get; set; }

Property Value

InteractionError?

Remarks

Written by IIdentityServerInteractionService.DenyAuthenticationAsync onto the state as it is stored and stored back under the same key, so settable, as Duende's is; the sign-on endpoint that resumes the state answers it with a SAML error status rather than an assertion.

DenialErrorDescription

The description given with DenialError, for the failure event; not sent to the service provider. Duende's.

public string? DenialErrorDescription { get; set; }

Property Value

string

ExpiresAt

When the state stops being resumable: Created plus SamlOptions.SigninStateLifetime. Duende's ExpiresAtUtc.

public DateTimeOffset? ExpiresAt { get; init; }

Property Value

DateTimeOffset?

Remarks

Null for a state written without one, which the in-memory store keeps for its own Lifetime.

PeerEntityId

The service provider that sent it, checked against the request when the state is resumed.

public required string PeerEntityId { get; init; }

Property Value

string

RedirectQuery

The query string a redirect-bound request arrived with, when it was signed there; null for a request that was not — one posted, signed inside its XML, or unsigned.

public string? RedirectQuery { get; init; }

Property Value

string

Remarks

A redirect-bound request is signed beside the message, over its query string (SAML Bindings §3.4.4.1), so the RequestXml kept for it carries no signature of its own. The endpoint checks the resumed request against this query, as it checked it on arrival, and answers the message the query carries. Until 0.179.0 it was not kept, and every such request that needed the login page was refused on its return as invalid_signature. A store of a host's own keeps it with the rest; a state stored without it is checked against its XML alone, as before.

RelayState

The RelayState the service provider sent, which says where the user was going.

public string? RelayState { get; init; }

Property Value

string

RequestId

The ID of the AuthnRequest this state belongs to, or null for an unsolicited sign-on.

public required string? RequestId { get; init; }

Property Value

string

RequestXml

The request itself, exactly as it was validated, or null when there was no request.

public required string? RequestXml { get; init; }

Property Value

string

Remarks

Null is what an IdP-initiated sign-on stores: there is no request to keep, and PeerEntityId is the whole of what the endpoint needs when the user comes back. The two endpoints share this store, so each refuses the other's state — answering a stored AuthnRequest from the unsolicited door would skip the validation the solicited door did on it, and resuming an unsolicited state at the solicited door would leave it with no request to answer.