Class ValidatingSamlServiceProviderStore
- Namespace
- Fdyay.IdentityServer.Saml.Idp
- Assembly
- Fdyay.IdentityServer.Saml.dll
Refuses a registered service provider that cannot be served, where it is read.
public sealed class ValidatingSamlServiceProviderStore : ISamlServiceProviderStore
- Inheritance
-
ValidatingSamlServiceProviderStore
- Implements
- Inherited Members
Remarks
Duende's counterpart to this and a caching decorator are the two store decorators this tree had not built. The reason recorded in 0.61.0 covered both — a caching decorator needs an invalidation story before it needs an implementation — and belonged to only one of them. This one needs no invalidation story at all: it is a pure function of the row it was handed, so it has nothing to go stale. It was also the half closing a real hole rather than saving a dictionary lookup.
On the read rather than at startup, and that is the point of it being a decorator. A registration known at startup could be checked there — 0.70.0 refuses an unusable signing certificate that way — but the registrations here come from an ISamlServiceProviderStore, which a host may back with a database that answers differently tomorrow. A startup check would be the rule applied to the half of the stores whose contents happen to be in memory.
An invalid registration reads as no registration, rather than throwing. That is what it is from every caller's point of view, it is the answer the endpoints already know how to give — they refuse an unknown service provider and raise their own event for it — and it keeps one host's broken registration from turning a sign-on into a 500. The specific reason goes to the log, because the endpoint's refusal can only say the entity id was not found and an operator looking at a registration that plainly exists needs to be told which field is the problem.
Constructors
ValidatingSamlServiceProviderStore(ISamlServiceProviderStore, IOptions<SamlOptions>, ILogger<ValidatingSamlServiceProviderStore>, ISamlServiceProviderConfigurationValidator?, IEventService?)
public ValidatingSamlServiceProviderStore(ISamlServiceProviderStore inner, IOptions<SamlOptions> options, ILogger<ValidatingSamlServiceProviderStore> logger, ISamlServiceProviderConfigurationValidator? validator = null, IEventService? events = null)
Parameters
innerISamlServiceProviderStoreThe store being validated.
optionsIOptions<SamlOptions>The SAML options, for the default validator when none is registered.
loggerILogger<ValidatingSamlServiceProviderStore>Where a refusal's reason is logged.
validatorISamlServiceProviderConfigurationValidatorDecides whether a registration can be served; Duende's seam since 0.117.0.
eventsIEventServiceWhere InvalidSamlServiceProviderConfigurationEvent is raised, when there is one.
Fields
InnerStoreKey
The key the wrapped store is registered under.
public const string InnerStoreKey = "Fdyay.IdentityServer.Saml.ServiceProviderStore.Unvalidated"
Field Value
Remarks
A key rather than the plain service type, because this wrapper is registered as that type itself. The
container still owns the inner store's lifetime and its disposal — the same arrangement
DataProtectingPersistedGrantStore uses, and for the same reason.
Methods
FindByEntityIdAsync(string, CancellationToken)
The registration with this entity id, or null when there is none to serve.
public Task<SamlServiceProvider?> FindByEntityIdAsync(string entityId, CancellationToken cancellationToken = default)
Parameters
entityIdstringThe service provider's entity id, compared exactly.
cancellationTokenCancellationTokenCancels the lookup.
Returns
- Task<SamlServiceProvider>
The registration, or null.
Remarks
Null when the inner store has no such provider, when it is disabled, or when the configuration validator refuses it — the last logged with its reason and raised as InvalidSamlServiceProviderConfigurationEvent.
GetAllSamlServiceProvidersAsync(CancellationToken)
Every provider the inner store holds that can be served, a disabled one included. Duende's, measured.
public IAsyncEnumerable<SamlServiceProvider> GetAllSamlServiceProvidersAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationToken
Returns
Remarks
Each refused registration is logged and raised as it is when it is looked up, and left out.