You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -315,13 +315,21 @@ public IActionResult Admin()
315
315
}
316
316
```
317
317
318
-
## Multiple Custom Domains
318
+
## Multiple Custom Domain (MCD) Support
319
319
320
-
The SDK supports scenarios where a single application needs to authenticate users against **multiple Auth0 tenants** or **custom domains**. This is useful for multi-tenant SaaS applications where each customer has their own Auth0 tenant.
320
+
Multiple Custom Domains (MCD) lets you resolve the Auth0 domain per request while keeping a single SDK instance. This is useful when one application serves multiple custom domains (for example, `brand-1.my-app.com` and `brand-2.my-app.com`), each mapped to a different `Auth0` custom domain.
321
321
322
-
### Basic Configuration
322
+
`MCD` is enabled by providing a `DomainResolver` function instead of a static domain string, enabling you to dynamically define the `Auth0` custom domain at run-time.
323
323
324
-
Enable Multiple Custom Domains by calling `WithCustomDomains()` and providing a `DomainResolver` function:
324
+
Resolver mode is intended for the custom domains of a single `Auth0` tenant. It is not a supported way to connect multiple `Auth0` tenants to one application.
325
+
326
+
### Dynamic Domain Resolver
327
+
328
+
Provide a resolver function to select the domain at runtime. The resolver should return the `Auth0 Custom Domain` (for example, `brand-1.custom-domain.com`). Returning `null` or an empty value throws `InvalidOperationException`.
329
+
330
+
### Configure with a DomainResolver
331
+
332
+
Call `WithCustomDomains()` and provide a `DomainResolver` to resolve the domain dynamically based on the incoming request. The domain can be derived from a subdomain, request header, query parameter, or any other request attribute:
The `DomainResolver` function receives the `HttpContext` and returns the Auth0 domain as a string. You can inspect any aspect of the HTTP request. The resolver can perform simple lookups or complex operations like querying a database:
When using MCD, the `redirectUri` must be an **absolute URL**. In MCD deployments, you will typically resolve the redirect URI per request so each domain uses the correct callback URL:
You must validate the host and scheme safely for your deployment to prevent open redirect attacks.
397
385
398
-
Control how OpenID Connect configurations are cached for each domain using `ConfigurationManagerCache`.
386
+
### Legacy sessions and migration
399
387
400
-
#### MemoryConfigurationManagerCache (Default)
388
+
When moving from a static domain setup to a `DomainResolver`, existing sessions can continue to work if the resolver returns the same Auth0 custom domain that was used for those legacy sessions.
389
+
390
+
If the resolver returns a different domain, the SDK treats the session as missing and requires the user to sign in again. This is intentional to keep sessions isolated per domain.
391
+
392
+
### Security requirements
393
+
394
+
When configuring the `DomainResolver`, you are responsible for ensuring that all resolved domains are trusted. Mis-configuring the domain resolver is a critical security risk that can lead to authentication bypass on the relying party (RP) or expose the application to Server-Side Request Forgery (SSRF).
395
+
396
+
**Single tenant limitation:**
397
+
The `DomainResolver` is intended solely for multiple custom domains belonging to the same Auth0 tenant. It is not a supported mechanism for connecting multiple Auth0 tenants to a single application.
398
+
399
+
**Secure proxy requirement:**
400
+
When using MCD, your application must be deployed behind a secure edge or reverse proxy (e.g., Cloudflare, Nginx, or AWS ALB). The proxy must be configured to sanitize and overwrite `Host` and `X-Forwarded-Host` headers before they reach your application.
401
+
402
+
Without a trusted proxy layer to validate these headers, an attacker can manipulate the domain resolution process. This can result in malicious redirects, where users are sent to unauthorized or fraudulent endpoints during the login and logout flows.
403
+
404
+
### Configuration Manager Cache
405
+
406
+
You can control how OpenID Connect configuration managers are cached per domain with `ConfigurationManagerCache`.
407
+
408
+
By default, the SDK uses an in-memory cache with:
409
+
-`maxSize: 100` entries
410
+
- No expiration (entries remain until evicted by size pressure)
411
+
412
+
The cache is keyed by the OIDC metadata endpoint URL (e.g., `https://brand-1.custom-domain.com/.well-known/openid-configuration`). Each distinct domain resolved by `DomainResolver` occupies one cache entry.
413
+
414
+
Most applications can keep the defaults, but you may want to adjust them in the following cases:
415
+
- Increase `maxSize` if one process may verify tokens for more than 100 distinct domains during its lifetime.
416
+
- Decrease `maxSize` if memory usage matters more than avoiding repeated OIDC discovery setup.
417
+
- Set `slidingExpiration` if you want entries that haven't been accessed within a given duration to be evicted automatically.
418
+
- Use `NullConfigurationManagerCache` to disable caching entirely (not recommended for production).
401
419
402
-
Caches configurations in memory with configurable size and expiration:
420
+
Rule of thumb: set `maxSize` to cover the number of distinct domains a single process is expected to serve, with some headroom.
3.**Token Validation**: The SDK automatically validates that tokens come from the expected issuer (the domain returned by your `DomainResolver`).
470
-
471
-
4.**Performance**: Use the default `MemoryConfigurationManagerCache` for most scenarios. The cache significantly reduces the overhead of fetching OIDC configuration for each request.
472
-
473
474
## Backchannel Logout
474
475
475
476
Backchannel logout can be configured by calling `WithBackchannelLogout()` when calling `AddAuth0WebAppAuthentication`.
Copy file name to clipboardExpand all lines: README.md
+8-13Lines changed: 8 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -114,9 +114,11 @@ For more code samples on how to integrate the **auth0-aspnetcore-authentication*
114
114
115
115
> This SDK also works with Blazor Server, for more info see [the Blazor Server section in our examples](https://github.com/auth0/auth0-aspnetcore-authentication/blob/main/EXAMPLES.md#blazor-server).
116
116
117
-
## Multiple Custom Domains
117
+
## Multiple Custom Domain (MCD) Support
118
118
119
-
The SDK supports scenarios where a single application needs to authenticate users against **multiple Auth0 tenants** or **custom domains**. This is useful for multi-tenant SaaS applications where each customer has their own Auth0 tenant.
119
+
Multiple Custom Domains (MCD) lets you resolve the Auth0 domain per request while keeping a single SDK instance. This is useful when one application serves multiple custom domains (for example, `brand-1.my-app.com` and `brand-2.my-app.com`), each mapped to a different `Auth0` custom domain.
120
+
121
+
Resolver mode is intended for the custom domains of a single `Auth0` tenant. It is not a supported way to connect multiple `Auth0` tenants to one application.
For detailed configuration options, caching strategies, and more examples, see the [Multiple Custom Domains Examples](EXAMPLES.md#multiple-custom-domains).
142
+
For detailed configuration options, caching strategies, security requirements, and more examples, see the [Multiple Custom Domain (MCD) Examples](EXAMPLES.md#multiple-custom-domain-mcd-support).
148
143
149
144
## API reference
150
145
Explore public API's available in auth0-aspnetcore-authentication.
0 commit comments