Search code examples
identityserver4

Is it possible to use a single client RedirectUri for multi-tenant application in IdentityServer 4?


I have an IdentityServer 4 setup using SaasKit to support multi-tenant URL paths. This allows me to access the single IS4 instance in a multi-tenant way like so:

https://localhost:5000/tenant/tenant1/.well-known/openid-configuration

The IS4 instance uses a single database for client/scope configuration rather than one per tenant. Only the users database is separated per tenant.

My issue is that a client only ever has one configuration and so has one RedirectUri and PostLogoutRedirectUri, and these values must be tenant specific URL paths otherwise the callback won't be handled in the context of a tenant in the client app.

So, I can specify in my client app's tenant-specific OpenIdConnectOptions new values for CallbackPath, SignedOutCallbackPath and RemoteSignOutPath, e.g. like this:

options.CallbackPath = $"/tenant/{tenant}{options.CallbackPath}";

but obviously this requires the relevant tenant fragment to be included in the client's config RedirectUri property otherwise IS4 will invalidate the redirect uri.

Whilst I could use dynamic clientIds from the client app, I'd prefer not to create a tenant-specific client config in IS4 for each tenant, and deal with the management issues. Likewise, I'd prefer not to add all possible tenant-specific redirect URIs to the single client's config.

Instead, is it possible to implement and register with IS4 some custom components that supports the following functionality, and if so which interfaces should I implement?

  1. A parameterized redirect URI path so the following can be specified: https://localhost:5000/tenant/{tenant}/signin-oidc
  2. Resolving a parameterized URI path into a real path when redirection is required.

Solution

  • You can implement a custom redirect URI validator.

    For that, you need to create a class that implements IRedirectUriValidator and then register it like this:

    services
        .AddIdentityServer(...)
        .AddRedirectUriValidator<MyCustomUriValidator>();
    

    This way you can set the redirect URI for the client in the database using some notation to specify the tenant-dependent part of the URI and then check it at runtime with the custom validator.

    Beware of the dangers associated with dynamic redirect URIs.