Open Closed

SSO and api calls #10200


User avatar
0
LiSong created

I have implemented SSO in a Next.js site using ABP.io, but when I call the API endpoints, I get a 401. Is there any doc on how to call an endpoint with the SSO token? thanks


2 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    1. Solution
    • What’s happening:

      • In an ABP solution with MVC UI (cookies as the default auth scheme), API endpoints challenge unauthenticated requests with a redirect to the login page. A non-browser client (like your Next.js app) must call those endpoints with a valid Bearer access token obtained from your SSO provider (OpenIddict/IdentityServer in ABP). If the request has no Bearer token (or the API is not configured to accept it), you’ll see 401 or an HTML login response.
    • End-to-end steps to call protected APIs from your Next.js app using the SSO token:

      1. Ensure your backend accepts JWT Bearer tokens on the API
      • In your HttpApi.Host module, configure JWT bearer authentication. ABP templates already do this, but verify that the AddJwtBearer config is present and the API resource scopes include your application’s scope.
      • If your Next.js app will access the backend from a different origin, add that origin to CORS.
      1. Register your Next.js client in IdentityServer/OpenIddict
      • Add a public SPA client using the authorization_code flow with PKCE, redirect URIs for your Next.js app, and proper CORS origins. This is done in IdentityServerDataSeedContributor (or OpenIddict seed) and appsettings (DbMigrator).
      • Typical settings:
        • Grant types: authorization_code
        • RequireClientSecret: false
        • RedirectUris: https://your-next-app.com/callback
        • PostLogoutRedirectUris: https://your-next-app.com
        • AllowedCorsOrigins: https://your-next-app.com
        • Scopes: openid profile email role phone address and your API scope (e.g., YourAppName)
        • Add offline_access if you need refresh tokens.
      1. Authenticate in Next.js and get the access token
      • Use an OIDC library that supports Code + PKCE in Next.js (e.g., next-auth with an OIDC provider, or a low-level OIDC client). After the callback completes, you will have an access_token.
      1. Attach the access token to API requests
      • From Next.js (on the server or client), include: Authorization: Bearer {access_token}
      • Example with fetch: const res = await fetch(${process.env.NEXT_PUBLIC_API_URL}/api/identity/my-profile, { headers: { Authorization: Bearer ${accessToken}, 'Accept-Language': 'en', // optional 'Abp-TenantId': tenantId ?? '' // if you use multi-tenancy and need to target a tenant } }); if (res.status === 401) { // handle re-auth or token refresh }
      1. Handle 401 vs. login redirects
      • Cookies scheme redirects to login for browser requests. When calling from your Next.js code via fetch/axios with Bearer tokens, you’ll see 401 on invalid/expired tokens (not the HTML login) as long as you don’t rely on cookie auth for those calls.
      • If you still get redirected HTML, ensure:
        • You are not sending the MVC cookie along with the API call.
        • You are targeting the HttpApi.Host URL (not the MVC UI host’s MVC action).
        • The request has a Bearer token and the API pipeline has JWT bearer enabled.
      1. Validate issuer when using tunnels/custom domains
      • If the Issuer differs from the Authority (e.g., ngrok/public URL), add ValidIssuers to AuthServer settings and configure TokenValidationParameters.ValidIssuers accordingly.
      1. Common pitfalls that cause 401:
      • Missing API scope in the requested scopes of the Next.js client.
      • Wrong authority/issuer in Next.js OIDC config.
      • CORS not allowing your Next.js origin.
      • Access token expired and no refresh handling.
    • Minimal code example (server-side Next.js API route proxying to ABP API):

    // /pages/api/me.ts
      import type { NextApiRequest, NextApiResponse } from 'next';
    
      export default async function handler(req: NextApiRequest, res: NextApiResponse) {
        const accessToken = req.headers['authorization']?.toString().replace(/^Bearer\s+/i, '');
        if (!accessToken) {
          return res.status(401).json({ error: 'No access token' });
        }
    
        const apiUrl = process.env.NEXT_PUBLIC_API_URL; // e.g. https://localhost:44350
        const r = await fetch(`${apiUrl}/api/identity/my-profile`, {
          headers: { Authorization: `Bearer ${accessToken}` }
        });
    
        if (!r.ok) {
          return res.status(r.status).send(await r.text());
        }
        return res.status(200).json(await r.json());
      }
    
    1. Sources
    • Support discussion about 401 vs login redirects and how API calls should use Authorization: Bearer:
      • https://abp.io/support/questions/611
    • Support discussion on 401 vs redirect behaviors in MVC and how requests differ:
      • https://abp.io/support/questions/3281
    • Community example showing attaching Bearer token and calling /api/identity/users:
      • https://abp.io/community/articles/aqjjwsdf
    • Community example showing getting tokens and posting to /connect/token (for reference on scopes/flows):
      • https://abp.io/community/articles/e74fmblw

    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.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Where is the token you're getting from? AuthServer?

    What are the details of the 401 logs? See debug logs.

    https://abp.io/support/questions/8622/How-to-enable-Debug-logs-for-troubleshoot-problems

    Thanks.

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.1.0-preview. Updated on December 10, 2025, 12:02
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.