Table of Contents

Class SamlSingleLogoutEndpoint

Namespace
Fdyay.IdentityServer.Saml.Endpoints
Assembly
Fdyay.IdentityServer.Saml.dll

The SAML 2.0 IdP Single Logout endpoint: ends the session, propagates it, and answers the requester.

public sealed class SamlSingleLogoutEndpoint : IEndpointHandler
Inheritance
SamlSingleLogoutEndpoint
Implements
Inherited Members

Remarks

The session is only destroyed for a LogoutRequest whose signature verifies against the service provider's registered certificate. A service provider with no certificate proves nothing about the origin of the request — entity ids are public — so its requests are handed to the logout page, which asks the user to confirm.

Single logout is a sequence, not a message. Ending the session and answering the one that asked is two of three steps: every other service provider the session reached has to be asked to end its own, and the requester is answered once they have. Each of those hops goes through the browser, so what is in flight — who asked, which request of theirs is owed an answer, who has not been told yet — lives in ISamlLogoutSessionStore and the browser carries an opaque reference to it. This endpoint therefore receives two kinds of message: a SAMLRequest that starts a sequence, and a SAMLResponse from a partner finishing its step of one.

The sign-out happens on the first pass and is not conditional on the rest. A partner that never answers, or answers unverifiably, leaves the sequence unfinished; it does not leave the user signed in here. That ordering is the whole guarantee this endpoint can actually make.

A logout failure is browser-facing — the browser was redirected here by the service provider — so it is shown to a person rather than returned as a bare status code: the detail is written to the shared ErrorMessage store and the browser is sent to UserInteraction.ErrorUrl with the opaque id, exactly as sign-on does.

Constructors

SamlSingleLogoutEndpoint(ISamlServiceProviderStore, IOptions<SamlOptions>, IOptions<IdentityServerOptions>, ILogoutContextFactory, IIssuerNameService, IMessageStore<ErrorMessage>, ISamlLogoutSessionStore, IHandleGenerationService, IUserSession, ISignOutService, IEventService, ISamlSigningService, TimeProvider, IServerUrls?)

The endpoint over the default SamlLogoutRequestValidator, given what it reads.

public SamlSingleLogoutEndpoint(ISamlServiceProviderStore serviceProviders, IOptions<SamlOptions> options, IOptions<IdentityServerOptions> identityServerOptions, ILogoutContextFactory logoutContexts, IIssuerNameService issuerNameService, IMessageStore<ErrorMessage> errorMessages, ISamlLogoutSessionStore logoutSessions, IHandleGenerationService handles, IUserSession userSession, ISignOutService signOut, IEventService events, ISamlSigningService signing, TimeProvider time, IServerUrls? urls = null)

Parameters

serviceProviders ISamlServiceProviderStore
options IOptions<SamlOptions>
identityServerOptions IOptions<IdentityServerOptions>
logoutContexts ILogoutContextFactory
issuerNameService IIssuerNameService
errorMessages IMessageStore<ErrorMessage>
logoutSessions ISamlLogoutSessionStore
handles IHandleGenerationService
userSession IUserSession
signOut ISignOutService
events IEventService
signing ISamlSigningService
time TimeProvider
urls IServerUrls

Remarks

Since 0.159.0 that validator is given userSession, which it matches a request against when asked.

SamlSingleLogoutEndpoint(ISamlServiceProviderStore, IOptions<SamlOptions>, IOptions<IdentityServerOptions>, ILogoutContextFactory, IIssuerNameService, IMessageStore<ErrorMessage>, ISamlLogoutSessionStore, IHandleGenerationService, IUserSession, ISignOutService, IEventService, ISamlSigningService, TimeProvider, ILogoutRequestValidator, IServerUrls?)

The endpoint over validator, which decides what a LogoutRequest must be. Duende's shape since 0.153.0.

public SamlSingleLogoutEndpoint(ISamlServiceProviderStore serviceProviders, IOptions<SamlOptions> options, IOptions<IdentityServerOptions> identityServerOptions, ILogoutContextFactory logoutContexts, IIssuerNameService issuerNameService, IMessageStore<ErrorMessage> errorMessages, ISamlLogoutSessionStore logoutSessions, IHandleGenerationService handles, IUserSession userSession, ISignOutService signOut, IEventService events, ISamlSigningService signing, TimeProvider time, ILogoutRequestValidator validator, IServerUrls? urls = null)

Parameters

serviceProviders ISamlServiceProviderStore
options IOptions<SamlOptions>
identityServerOptions IOptions<IdentityServerOptions>
logoutContexts ILogoutContextFactory
issuerNameService IIssuerNameService
errorMessages IMessageStore<ErrorMessage>
logoutSessions ISamlLogoutSessionStore
handles IHandleGenerationService
userSession IUserSession
signOut ISignOutService
events IEventService
signing ISamlSigningService
time TimeProvider
validator ILogoutRequestValidator
urls IServerUrls

Remarks

Whatever the validator answers, a session ends only for a request whose signature verifies against the provider it is from (HasTrustedSignature); any other is handed to the logout page for the user to confirm. urls is not read here — the validator checks the destination. Since 0.163.0 it answers through the default Saml2SloResponseGenerator over signing.

SamlSingleLogoutEndpoint(ISamlServiceProviderStore, IOptions<SamlOptions>, IOptions<IdentityServerOptions>, ILogoutContextFactory, IIssuerNameService, IMessageStore<ErrorMessage>, ISamlLogoutSessionStore, IHandleGenerationService, IUserSession, ISignOutService, IEventService, ISamlSigningService, TimeProvider, ILogoutRequestValidator, ISaml2SloResponseGenerator, IServerUrls?)

The endpoint over validator, answering the provider that asked through responseGenerator, the host's ISaml2SloResponseGenerator. Since 0.163.0.

public SamlSingleLogoutEndpoint(ISamlServiceProviderStore serviceProviders, IOptions<SamlOptions> options, IOptions<IdentityServerOptions> identityServerOptions, ILogoutContextFactory logoutContexts, IIssuerNameService issuerNameService, IMessageStore<ErrorMessage> errorMessages, ISamlLogoutSessionStore logoutSessions, IHandleGenerationService handles, IUserSession userSession, ISignOutService signOut, IEventService events, ISamlSigningService signing, TimeProvider time, ILogoutRequestValidator validator, ISaml2SloResponseGenerator responseGenerator, IServerUrls? urls = null)

Parameters

serviceProviders ISamlServiceProviderStore
options IOptions<SamlOptions>
identityServerOptions IOptions<IdentityServerOptions>
logoutContexts ILogoutContextFactory
issuerNameService IIssuerNameService
errorMessages IMessageStore<ErrorMessage>
logoutSessions ISamlLogoutSessionStore
handles IHandleGenerationService
userSession IUserSession
signOut ISignOutService
events IEventService
signing ISamlSigningService
time TimeProvider
validator ILogoutRequestValidator
responseGenerator ISaml2SloResponseGenerator
urls IServerUrls

Remarks

The longest constructor, the one the container takes; urls is not read, and is here so this constructor's parameters include every other's, as the container requires of the one it picks.

Methods

ProcessAsync(HttpContext)

Processes the request, or returns null to pass the request through.

public Task<IEndpointResult?> ProcessAsync(HttpContext context)

Parameters

context HttpContext

Returns

Task<IEndpointResult>

Remarks

Null — the request passes through — for a binding SingleLogoutServiceBindings does not list. A SAMLResponse continues a sequence this server started; a SAMLRequest starts one; a request carrying neither is answered 400. Refusals after that go to the error page.

Exceptions

ArgumentNullException

context is null.