Open Closed

Forward __tenant as query string to Authentication Server #9140


User avatar
0
JimmyLiew created

Hi, I have implemented subdomain tenant resolver in angular frontend by adding {0} placeholder to determine current tenant.

Noticed that, when angular redirect to auth-server, __tenant custom header does not forward due to the redirect with 302 status code behavior. (Please correct me if I'm wrong.) https://stackoverflow.com/questions/46133557/why-is-my-header-not-being-set-on-redirect

Workaround Solution - Pass __tenant as query string instead of request header.

Question: As per abp documentation, abp backend already built-in QueryStringTenantResolveContributor to resolve the tenant by trying to find current tenant id from query string parameters. May i know how to implement QueryStringTenantResolveContributorin frontend so that "__tenant" will append as query string in URL and forwards to authentication server and trigger QueryStringTenantResolveContributor to resolve tenant seamlessly?

For example: Angular : https://tenant1.app.example.com AuthServer: https://auth-server.example.com?__tenant=tenant1

Thanks.


24 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    The angular this.authService.navigateToLogin(); can accept queryParams?: Params

    You can add __tenant to this method.

    https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts#L78-L86 https://abp.io/docs/latest/framework/ui/angular/component-replacement

  • User Avatar
    0
    JimmyLiew created

    Hi,

    Thanks for prompt response. I’ve added __tenant as a parameter in this.authService.navigateToLogin(). The Authentication Server correctly resolves the tenant and pre-fills the tenant input field. However, the tenant input field is still visible. Is there a way to hide the tenant input field if the tenant is successfully resolved, and only display it when the tenant cannot be identified? Does ABP automatically hide the tenant input field when the tenant is successfully resolved, or do I need to implement the logic explicitly to hide it?

    Thanks.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    The tenant switch element will show if the current tenant is getting from Cookie or QueryString

    You can considering to override the Account layout

    eg: https://github.com/abpframework/abp/blob/dev/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml#L64-L66

  • User Avatar
    0
    JimmyLiew created

    Hi,

    I have encountered an issue when trying to logout from angular frontend.

    Steps to Reproduce i) Pass __tenant as query string.

    ii) click on login button with __tenant query string attached and redirect to authentication server.

    iii)There is no response after clicking on logout button.

    Could you please advise if I missed any implementations?

    Thanks.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Please share the har file of all requests and responses of Chrome.

    liming.ma@volosoft.com

  • User Avatar
    0
    JimmyLiew created

    Hi,

    Sent.

    Thanks.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    There is no logout request in your HAR file.

    Can you share an online URL, username, and password? I will log in and test the logout function.

    Thanks.

    liming.ma@volosoft.com

  • User Avatar
    0
    JimmyLiew created

    Hi

    Sent.

    Thanks.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    The error happened if the current URL ends with /?&&

    https://abp.io/?&&

    main.0b1b96b4092c5d26.js:1 ERROR TypeError: Cannot read properties of undefined (reading 'toggle')
        at M.toggleCtxMenu (main.0b1b96b4092c5d26.js:1:1484387)
        at main.0b1b96b4092c5d26.js:1:1485112
        at Q1 (main.0b1b96b4092c5d26.js:1:758941)
        at Object.r [as next] (main.0b1b96b4092c5d26.js:1:759098)
        at ye.next (main.0b1b96b4092c5d26.js:1:255667)
        at Qe._next (main.0b1b96b4092c5d26.js:1:255334)
        at Qe.next (main.0b1b96b4092c5d26.js:1:255018)
        at main.0b1b96b4092c5d26.js:1:252848
        at u (main.0b1b96b4092c5d26.js:1:280735)
        at Ru.next (main.0b1b96b4092c5d26.js:1:252685)
    

    Can you create a new question to ask the Angular team?

    Thanks.

  • User Avatar
    0
    JimmyLiew created

    Hi,

    I have sent you an email regarding how to reproduce the issue. Please have a look.

    Thanks.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share the online website URL again? Our angular team will check it.

    This is related to Angular.

    Thanks.

  • User Avatar
    0
    JimmyLiew created

    Hi,

    Sent via email.

    Thanks

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Thanks. We will check it asap.

  • User Avatar
    0
    JimmyLiew created

    Hi,

    May I know any update?

    Thanks.

  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Hello, I will check and get back to you soon. Thank you for your patience and cooperation.

  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Hello! I've implemented a similar Angular application and applied the same modifications to the login button, but I’m unable to reproduce the issue on my end. To assist you more effectively, could you please share a minimal, reproducible example?

    That way, I can help debug the issue more precisely.

  • User Avatar
    0
    JimmyLiew created

    Hi,

    Can I have your email? I will share u the minimal project to reproduce the issue.

    Thanks.

  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Sure, I forgot sharing my address. You can email me via sumeyye.kurtulus@volosoft.com

  • User Avatar
    0
    JimmyLiew created

    Hi

    Sent via email.

    Thanks.

  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Thank you for sharing the additional details. After reviewing your project and running a few tests, it appears that the issue stems from redundant query parameters in the URL. As a temporary workaround, we recommend sanitizing the URL before passing it to Angular’s router or any relevant authentication service.

    In the meantime, you can try implementing the following provider-based approach to handle this. Please let us know if this resolves the issue on your end while we continue investigating and work toward a permanent fix.

    // url-sanitizer.ts
    import { provideAppInitializer } from '@angular/core';
    
    export const SANITIZE_URL = [
      provideAppInitializer(() => {
        sanitizeStartupUrl();
      }),
    ];
    export function sanitizeStartupUrl() {
      const currentUrl = window.location.href;
    
      if (currentUrl.endsWith('?&&')) {
        const cleanUrl = window.location.origin + window.location.pathname;
        window.location.replace(cleanUrl);
      }
    }
    
    // app.module.ts
    @NgModule({
      providers: [
        ...
        SANITIZE_URL,
      ],
      bootstrap: [AppComponent],
    })
    export class AppModule {}
    
  • User Avatar
    0
    JimmyLiew created

    Hi,

    I 've implemented the code you suggested in my application, but the issue still persists. Could you advice?

    Thanks.

  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Thank you for following up, and I am sorry to hear the issue is still persisting.

    Since this behavior doesn’t occur in development, it’s likely related to how the application is built or served in production — potentially during the deployment phase. That could be why the query string isn’t being cleaned up as expected.

    In the meantime, here's a quick way to programmatically remove any unwanted query like ?&& from the URL once the app loads:

    export class AppComponent implements OnInit {
      private router = inject(Router);
    
      ngOnInit() {
        const rawQuery = window.location.search;
        const isGarbageQuery = rawQuery && rawQuery.match(/^(\?&+)+$/);
    
        if (isGarbageQuery) {
          const url = this.router.url.split('?')[0];
          this.router.navigateByUrl(url, { replaceUrl: true });
        }
      }
    }
    

    This ensures the URL is cleaned without reloading the page.

    Let me know if you would need further assistance on that. Thank you for your cooperation.

  • User Avatar
    0
    JimmyLiew created

    Hi,

    I have implemented workaround solution as you suggested. However, the issue still unable to resolve. Has the workaround been tested and confirmed to work on your end? If not, could you please provide a verified working solution instead?"

    Remarks: This issue is happened for all the environments(Development and Production build)

    Thanks.

  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Thank you for your continued effort and patience — I understand you've already tried several approaches.

    We’ve tried reproducing the issue on both development and production builds, but unfortunately haven’t been able to replicate it so far. Because of that, we’re unable to provide a guaranteed fix at this point.

    That said, based on your description, this doesn’t appear to be directly related to Angular’s routing. It’s more likely caused by a deployment or infrastructure-level behavior. Could you please check the following:

    • Are there any redirects or rewrites (e.g. in NGINX, Apache, or a CDN) that might be preserving or appending query strings?
    • Is there a proxy or load balancer in place that could be modifying request URLs or injecting ?&& patterns?
    • Could there be any old links or external redirects pointing to your app with malformed URLs?

    If possible, setting up URL rewrites to strip or sanitize these query strings (e.g. redirecting to a clean / path) might help resolve the issue.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.3.0-preview. Updated on April 16, 2025, 12:13