Activities of "gouda"

Environment

  • ABP Commercial 9.3.7
  • UI: Angular
  • Authentication: separate Auth Server using OpenIddict
  • Multi-tenancy: domain/sub-domain tenant resolver
    • Host: mydomain.com
    • Tenants: {tenant}.mydomain.com
    • Configured with AddDomainTenantResolver and AbpOpenIddictWildcardDomainOptions

Goal

When a user switches to a linked account in another tenant, the browser should be redirected to that tenant's sub-domain so the application loads under the correct tenant URL.

1. Which options class should be used for Angular + OpenIddict?

The documentation and forum posts (for example, #7425) configure AbpAccountOptions:

Configure<AbpAccountOptions>(options =>
{
    options.IsTenantMultiDomain = true;
    options.GetTenantDomain = (httpContext, info) =>
        Task.FromResult(/* tenant URL */);
});

In our Angular + OpenIddict setup, this had no effect. However, configuring AbpAccountOpenIddictOptions works:

Configure<AbpAccountOpenIddictOptions>(options =>
{
    options.IsTenantMultiDomain = true;
    options.GetTenantDomain = (httpContext, info) =>
        Task.FromResult(/* tenant URL */);
});

We could not find any documentation for AbpAccountOpenIddictOptions.

2. IsTenantMultiDomain causes a duplicate tenant_domain parameter

After enabling IsTenantMultiDomain, the grant_type=LinkLogin request to /connect/token fails with HTTP 500:

A parameter with the same name already exists. (Parameter 'name')

The exception originates from LinkLoginExtensionGrantProcessJsonResponse. From debugging, it appears that:

  1. LinkLoginExtensionGrant adds tenant_domain.
  2. LinkLoginExtensionGrantProcessJsonResponse attempts to add tenant_domain again, causing the exception.

Our workaround is:

PreConfigure<OpenIddictServerBuilder>(builder =>
{
    builder.RemoveEventHandler(
        LinkLoginExtensionGrantProcessJsonResponse.Descriptor
    );
});

After removing the handler, tenant_domain is still included in the response and account switching works correctly.

3. Cross-domain switch passes tokens in the URL

For cross-sub-domain account switching, Angular's LinkLoginHandler redirects with the tokens embedded in the query string (single line, shown wrapped for readability):

https://tenant.mydomain.com?handler=linkLogin&token={"access_token":"...","refresh_token":"...","access_token_stored_at":...,"expires_at":...}

The destination application reads the token payload from the query parameters and stores it in localStorage.

Questions

  1. Is AbpAccountOpenIddictOptions the correct and supported configuration for Angular + OpenIddict linked-account switching?
  2. Are the duplicate tenant_domain exception and the need to remove LinkLoginExtensionGrantProcessJsonResponse a known issue, or is there a recommended fix?
  3. Is redirecting to the target tenant sub-domain and passing tokens in the URL the recommended approach for cross-tenant linked-account switching? If not, does ABP provide a more secure alternative that achieves the same result?
Showing 1 to 1 of 1 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on September 28, 2026, 11:44
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.