Open Closed

Shared User Account - Implement for other frontend #10625


User avatar
0
thanhvl1 created

Hi,

I'm using Abp v10.3 with feature Shared User Account that allow me do "One account, multiple tenant", I see in UI of auth-server and angular has this option "switch tenant" and I want to ask how to implement it in other frontend ( my other frontend is using Nextjs and I want to implement the same this feature)

Can you please give me a guide to implement this

Thanks in advance

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

4 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • In ABP, “switch tenant” in the UI is just changing the current tenant context for the frontend, and then ensuring every API call includes the tenant information.
    • For a custom frontend (Next.js) you implement the same idea by:
      1. getting the available tenants for the logged-in user (for Shared User Accounts),
      2. letting the user pick one,
      3. persisting the selection (cookie/localStorage/session),
      4. sending the tenant to the backend on every request as the __tenant header (or query string when needed).

    1) Persist “current tenant” in your Next.js app

    Pick one storage mechanism:

    • Cookie (recommended; works for SSR and API routes)
    • LocalStorage (only client-side)

    Example (cookie):

    • Store abp_tenant = tenant name (or id, depending on your backend usage; ABP commonly resolves by name in UI switchers).

    2) Send the tenant on every API request (__tenant header)

    ABP Angular UI does this: it reads the selected tenant and sends it as __tenant header on each request.

    In Next.js, do the same in your API client wrapper:

    // apiClient.ts
    export async function abpFetch(input: RequestInfo, init: RequestInit = {}) {
      const headers = new Headers(init.headers);
    
      // Read from cookie (client-side example)
      const tenant = document.cookie
        .split("; ")
        .find(x => x.startsWith("abp_tenant="))
        ?.split("=")[1];
    
      if (tenant) {
        headers.set("__tenant", decodeURIComponent(tenant));
      }
    
      return fetch(input, { ...init, headers });
    }
    

    If you also do SSR, read the cookie from the incoming request in getServerSideProps / route handlers and forward __tenant.

    3) Create a “tenant switcher” UI

    • Call an endpoint to list tenants the current user can switch to (Shared User Accounts feature provides this capability via the Account/Identity Pro modules).
    • When the user selects a tenant:
      1. write cookie abp_tenant=<tenantName>
      2. reload the app (so SSR + cached config reflect new tenant)
      3. subsequent API calls include __tenant

    4) After switching: refresh “application configuration” and auth context

    In ABP UIs, the selected tenant also affects application-configuration (and what menus/features are visible). In your Next.js app, after setting the tenant cookie/header:

    • re-fetch your “bootstrap” data (profile, permissions, menus, etc.) under the new tenant context.
    • if you cache tokens/claims client-side, note that ABP re-issues auth context when switching in its own UI. In a custom UI, the safest approach is: reload and re-fetch user/permission-related data after tenant change.

    5) Login/redirect flows (important)

    If your login is done via the ABP Auth Server pages, tenant selection can be involved in the login UX. In custom SPAs, it’s common to:

    • let user login first,
    • then show “select tenant” if multiple tenants are available,
    • then set __tenant for API calls.

    (If you must pass tenant during auth redirects, ABP UIs pass tenant via request parameters/headers depending on flow; the key concept remains: tenant context must be resolved on the server side.)


    References (validated)

    • https://abp.io/docs/latest/modules/account/shared-user-accounts
    • https://abp.io/docs/latest/framework/ui/angular/multi-tenancy
    • https://abp.io/community/articles/mf3bkg79

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Hi,

    The "Switch Tenant" feature relies on a custom OpenIddict extension grant (SwitchTenant) plus a few /api/account/user-sharing endpoints. Here is everything you need to wire it up in Next.js.

    1. Detect if Shared mode is enabled

    Read multiTenancy.userSharingStrategy from the application configuration endpoint. Only show the "Switch tenant" UI when it equals 1 (Shared).

    GET {HttpApiHost}/api/abp/application-configuration
    
    {
      "multiTenancy": {
        "isEnabled": true,
        "userSharingStrategy": 1   // 0 = Isolated, 1 = Shared
      }
    }
    

    2. Get the list of tenants the current user is shared with

    GET {HttpApiHost}/api/account/user-sharing
    Authorization: Bearer <current_access_token>
    

    Response:

    {
      "items": [
        { "tenantId": "guid-or-null", "tenantName": "TenantA", "email": "user@x.com" },
        { "tenantId": "guid-or-null", "tenantName": "TenantB", "email": "user@x.com" }
      ]
    }
    

    3. Switch tenant via the custom SwitchTenant grant type

    This is the key part. Post to the AuthServer token endpoint with grant_type=SwitchTenant. The current access_token is sent as a parameter (the grant handler introspects it to identify the user) and a new token set scoped to the target tenant is returned.

    POST {AuthServerUrl}/connect/token
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=SwitchTenant
    &client_id=<your_client_id>
    &client_secret=<your_client_secret>      // only for confidential clients
    &access_token=<current_valid_access_token>
    &TenantId=<target_tenant_guid>           // omit / leave empty to switch to Host
    

    Response is a standard OAuth token response:

    {
      "access_token": "...",
      "refresh_token": "...",
      "id_token": "...",
      "token_type": "Bearer",
      "expires_in": 3600,
      "scope": "..."
    }
    

    The new access_token already has the target tenant's tenantid claim, so every subsequent API call will run in the new tenant context.

    After receiving the response in Next.js you should:

    • Replace the stored access_token / refresh_token / id_token
    • Reload the app (or re-initialize state) so all subsequent requests use the new tokens

    This is exactly what Angular does — see SwitchTenantService in commercial-ui/config/src/services/switch-tenant.service.ts, which calls loginUsingGrant('SwitchTenant', { TenantId }) and then location.href = baseUrl to refresh.

    4. Leave a shared tenant (optional)

    DELETE {HttpApiHost}/api/account/user-sharing/leave?tenantId=<guid>
    Authorization: Bearer <current_access_token>
    

    5. Invitation endpoints (if you need invite/accept/reject in your UI)

    GET  /api/account/user-sharing/invitation?token=<inviteToken>
    POST /api/account/user-sharing/invitation/accept   // body: { token, ... }
    POST /api/account/user-sharing/invitation/reject   // body: { token, ... }
    

    Backend prerequisites (just to confirm)

    Configure<AbpMultiTenancyOptions>(options =>
    {
        options.IsEnabled = true;
        options.UserSharingStrategy = TenantUserSharingStrategy.Shared;
    });
    

    If UserSharingStrategy is not Shared, the SwitchTenant grant returns unsupported_grant_type.

    TL;DR for the Next.js side

    1. GET /api/abp/application-configuration → check multiTenancy.userSharingStrategy === 1
    2. GET /api/account/user-sharing → render the tenant list
    3. On selection: POST /connect/token with grant_type=SwitchTenant&access_token=<current>&TenantId=<guid>
    4. Save the new tokens and reload the app

    Thanks

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    thanhvl1 created

    thanks for your guide, I implemented follow this guide and it worked

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Great 👍

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
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 09, 2026, 11:56
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.