Table of Contents

Class DynamicAuthenticationSchemeProvider

Namespace
Fdyay.IdentityServer.Hosting
Assembly
Fdyay.IdentityServer.AspNetCore.dll

Hands out stored identity providers as authentication schemes, so everything that already asks what schemes exist finds them without knowing they are stored.

public sealed class DynamicAuthenticationSchemeProvider : IAuthenticationSchemeProvider
Inheritance
DynamicAuthenticationSchemeProvider
Implements
Inherited Members

Remarks

A decorator rather than a parallel lookup, and that is the whole design. Three places already ask this question and each of them is a rule somebody would otherwise have to remember to extend: the sign-in page builds its provider list from GetAllSchemesAsync, the idp: home-realm hint is matched against that same list, and ISignOutService resolves the idp claim through GetSchemeAsync to decide whether a sign-out is carried on to the provider that started the session. A dynamic scheme that did not appear here would be offerable, signed in through, and then silently not signed out of — 0.42.0's defect, reintroduced by the feature that came after it.

GetRequestHandlerSchemesAsync is the one list a dynamic provider is deliberately not in, since 0.104.0, as it is not in Duende's. The authentication middleware asks every scheme on it about every request, so listing stored providers there read the store on every request the server answered. A dynamic provider's callback is routed by Fdyay.IdentityServer.Hosting.DynamicSchemeAuthenticationMiddleware instead, to its own handler only.

Constructors

DynamicAuthenticationSchemeProvider(IAuthenticationSchemeProvider, IServiceScopeFactory, IServiceProvider, DynamicProviderCache, IOptions<DynamicProviderOptions>)

The store is read through a scope of its own rather than injected, because this provider is a singleton and has to be: AuthenticationMiddleware is constructed from the root provider, so a scoped dependency here would be captured by it.

public DynamicAuthenticationSchemeProvider(IAuthenticationSchemeProvider inner, IServiceScopeFactory scopes, IServiceProvider services, DynamicProviderCache cache, IOptions<DynamicProviderOptions> options)

Parameters

inner IAuthenticationSchemeProvider
scopes IServiceScopeFactory
services IServiceProvider
cache DynamicProviderCache
options IOptions<DynamicProviderOptions>

Remarks

The root provider is taken as well, and only for one thing: dropping a scheme's cached options when its row has changed. What holds them is IOptionsMonitorCache<TOptions>, whose options type is known per registered kind rather than here, so the drop is asked of DynamicProviderOptions — which closes over the kind's options type — and needs a provider to resolve it from. It is a singleton, so there is no scope to capture.

Methods

AddScheme(AuthenticationScheme)

Adds a static scheme to the inner provider; a dynamic provider is added by writing it to the store instead.

public void AddScheme(AuthenticationScheme scheme)

Parameters

scheme AuthenticationScheme

The scheme to add.

GetAllSchemesAsync()

The statically registered schemes, then every enabled stored provider whose name none of them has and whose kind is registered.

public Task<IEnumerable<AuthenticationScheme>> GetAllSchemesAsync()

Returns

Task<IEnumerable<AuthenticationScheme>>

The schemes.

GetDefaultAuthenticateSchemeAsync()

Returns the scheme that will be used by default for AuthenticateAsync(HttpContext, string). This is typically specified via DefaultAuthenticateScheme. Otherwise, this will fallback to DefaultScheme.

public Task<AuthenticationScheme?> GetDefaultAuthenticateSchemeAsync()

Returns

Task<AuthenticationScheme>

The scheme that will be used by default for AuthenticateAsync(HttpContext, string).

GetDefaultChallengeSchemeAsync()

Returns the scheme that will be used by default for ChallengeAsync(HttpContext, string, AuthenticationProperties). This is typically specified via DefaultChallengeScheme. Otherwise, this will fallback to DefaultScheme.

public Task<AuthenticationScheme?> GetDefaultChallengeSchemeAsync()

Returns

Task<AuthenticationScheme>

The scheme that will be used by default for ChallengeAsync(HttpContext, string, AuthenticationProperties).

GetDefaultForbidSchemeAsync()

Returns the scheme that will be used by default for ForbidAsync(HttpContext, string, AuthenticationProperties). This is typically specified via DefaultForbidScheme. Otherwise, this will fallback to GetDefaultChallengeSchemeAsync() .

public Task<AuthenticationScheme?> GetDefaultForbidSchemeAsync()

Returns

Task<AuthenticationScheme>

The scheme that will be used by default for ForbidAsync(HttpContext, string, AuthenticationProperties).

GetDefaultSignInSchemeAsync()

Returns the scheme that will be used by default for SignInAsync(HttpContext, string, ClaimsPrincipal, AuthenticationProperties). This is typically specified via DefaultSignInScheme. Otherwise, this will fallback to DefaultScheme.

public Task<AuthenticationScheme?> GetDefaultSignInSchemeAsync()

Returns

Task<AuthenticationScheme>

The scheme that will be used by default for SignInAsync(HttpContext, string, ClaimsPrincipal, AuthenticationProperties).

GetDefaultSignOutSchemeAsync()

Returns the scheme that will be used by default for SignOutAsync(HttpContext, string, AuthenticationProperties). This is typically specified via DefaultSignOutScheme. Otherwise, this will fallback to GetDefaultSignInSchemeAsync() .

public Task<AuthenticationScheme?> GetDefaultSignOutSchemeAsync()

Returns

Task<AuthenticationScheme>

The scheme that will be used by default for SignOutAsync(HttpContext, string, AuthenticationProperties).

GetRequestHandlerSchemesAsync()

The static schemes only. See the remarks on this class.

public Task<IEnumerable<AuthenticationScheme>> GetRequestHandlerSchemesAsync()

Returns

Task<IEnumerable<AuthenticationScheme>>

GetSchemeAsync(string)

The scheme of that name: a statically registered one first, otherwise the stored provider of that name as a DynamicAuthenticationScheme — or null when there is neither, the row is disabled, or its kind is not registered.

public Task<AuthenticationScheme?> GetSchemeAsync(string name)

Parameters

name string

The scheme name.

Returns

Task<AuthenticationScheme>

The scheme, or null.

RemoveScheme(string)

Removes a static scheme from the inner provider; a dynamic provider is removed from the store instead.

public void RemoveScheme(string name)

Parameters

name string

The scheme name.