Customer Portal SSO via JWT

Modified on Thu, 11 Sep at 9:50 AM

Configuring JWT Single Sign-On (SSO) with Benji Pays

To enable Single Sign-On (SSO) using JSON Web Tokens (JWT) in Benji Pays, follow the steps outlined below. This guide will ensure your integration meets the requirements for secure authentication.

Step 1: Set Up the SSO Configuration in Benji Pays

  1. Log in to Benji Pays.
  2. Navigate to Settings » Customer Portal Settings » SSO Configuration.
  3. Click on Add Configuration.
  4. Select JWT as the SSO type.

Complete the Form

  • Description: Provide a descriptive name for this SSO configuration.
  • Remote Login URL: Enter the URL where users will be sent to log in on your system (e.g., https://your-sso-provider.com/login). This is also where users will be redirected if authentication errors occur.
  • Login Redirect URL: This URL is automatically generated. It points to the callback endpoint on Benji Pays (e.g., https://yourportaldomain.com/callbackjwt).
  • ISS (Issuer): This value will act as the iss claim in your JWT payload.
  • Login Button Text: Customize the button text that users will see for SSO login.

Once the form is complete, click Save.

Obtain Key Configuration Details

After saving, the form will display the following critical information that you'll need to configure your JWT:

  • AUDIENCE: The expected audience (aud) for the JWT.
  • ISSUER (ISS): The value to include in the iss claim.
  • CLIENTID: Your unique client identifier.
  • CLIENTSECRET: Your shared secret for signing JWTs.

Step 2: Generate the JWT

Your system will generate a JWT containing the required claims and send it as part of the authentication process.

JWT Requirements

  1. Header:
  2. {
      "alg": "HS256",
      "typ": "JWT"
    }
      
  3. Payload:
  4. The payload must include the following claims:

    • iss (Issuer): Use the value provided in the ISS field from your SSO configuration.
    • aud (Audience): Use the value provided in the AUDIENCE field.
    • exp (Expiration Time): The token must expire no more than 5 minutes from the time of issuance.
    • iat (Issued At): The time the token was issued.  The token must not have been issued more than 30 seconds in the past when Benji Pays receives it.
    • email: The email address of the user.
    • sub: This is the unique ID for your user that will not change and is unique and does not match their email address.
    • client_id: The unique Client ID provided in your SSO configuration.
    • NEW: emailVerified (Optional): Boolean value indicating if the user's email has been verified by your system. See Email Verification section below.
  5. Example Payload (Basic):

    {
      "iss": "paxxxxxps-jwt-dxxxxxx4",
      "aud": "BENJIPAYS",
      "exp": 1700000000,
      "iat": 1699999400,
      "email": "user@example.com",
      "sub": "user_12345",
      "client_id": "provided-client-id"
    }
      
  6. Example Payload (With Email Verification):

    {
      "iss": "paxxxxxps-jwt-dxxxxxx4",
      "aud": "BENJIPAYS",
      "exp": 1700000000,
      "iat": 1699999400,
      "email": "user@example.com",
      "sub": "user_12345",
      "client_id": "provided-client-id",
      "emailVerified": true
    }
      
  7. Signature:
  8. The JWT must be signed using the CLIENTSECRET with the HS256 algorithm.

Email Verification (NEW FEATURE)

You can now indicate whether a user's email has been verified by your system, eliminating redundant verification steps.

How It Works

  • With emailVerified: true - User goes directly to the dashboard (no email verification required)
  • With emailVerified: false or missing - User must verify their email through Benji Pays (traditional flow)

Usage Examples

Skip Email Verification (Recommended for verified users):

const token = jwt.sign({
  // ... required claims ...
  emailVerified: true  // User has verified email in your system
}, clientSecret);

Require Email Verification:

const token = jwt.sign({
  // ... required claims ...
  emailVerified: false  // Or omit this claim entirely
}, clientSecret);

Security Requirements

  • Only boolean true is trusted - Strings like "true" or numbers like 1 will be ignored
  • Use only for verified emails - Only set emailVerified: true if you have actually verified the user's email
  • Backward compatible - Existing integrations continue to work without changes

Step 3: Submit the JWT

Once the JWT is generated, it must be submitted via a POST request to the /callbackjwt endpoint.

Form Submission

  • Form Method: POST
  • Action: https://yourportaldomain.com/callbackjwt
  • Hidden Form Field:
    • Name: token
    • Value: The JWT string.

Example Form:

<!DOCTYPE html>
<html>
<head>
  <title>SSO Login</title>
</head>
<body>
  <form action="https://yourportaldomain.com/callbackjwt" method="POST">
    <input type="hidden" name="token" value="YOUR_JWT_HERE">
    <button type="submit">Login with ACME Co.</button>
  </form>
  <script>
    // Optional: Auto-submit the form
    document.forms[0].submit();
  </script>
</body>
</html>

Step 4: Authentication Flow

  1. Users click the SSO login button in the customer portal.
  2. They are redirected to your system’s login page via the Remote Login URL.
  3. After successful login on your system, your system generates a JWT and submits it to the /callbackjwt endpoint via the hidden form field.
  4. Benji Pays validates the JWT and either:
    • If emailVerified: true - Logs the user directly into the customer portal
    • If emailVerified: false/missing - Prompts for email verification first

Error Handling and User Experience

Benji Pays now provides improved error handling for JWT SSO with human-readable error codes:

JWT SSO Error Scenarios

JWT SSO developers will encounter these specific error codes when authentication issues occur:

  • Account Not Found: ?error=account-not-found
    The user's email address is not associated with any account in the system, or they don't have access to any companies with enabled portals.
  • Account Disabled: ?error=account-disabled
    The user's account has been disabled by an administrator.
  • Email Verification Required: ?error=email-verification-required
    The user needs to verify their email address through the SSO email verification process before accessing the portal.

Note: These are the primary error codes you'll encounter in JWT SSO implementations. Other error codes exist in the system but are specific to Auth0/OIDC SSO flows or internal processes that JWT developers won't encounter.

Handling Error Redirects

Your Remote Login URL should handle these error parameters to display appropriate messages:

// JWT SSO error handling example
const urlParams = new URLSearchParams(window.location.search);
const error = urlParams.get('error');

if (error) {
  let message = '';

  switch(error) {
    case 'account-not-found':
      message = 'Account not found. Please contact support or check your email address.';
      break;
    case 'account-disabled':
      message = 'Your account has been disabled. Please contact support for assistance.';
      break;
    case 'email-verification-required':
      message = 'Please verify your email address to continue accessing the portal.';
      break;
    default:
      message = 'Authentication error occurred. Please try again or contact support.';
  }

  showErrorMessage(message);
}

function showErrorMessage(message) {
  // Example implementation - adapt to your UI framework
  const messageDiv = document.createElement('div');
  messageDiv.className = 'alert alert-danger';
  messageDiv.textContent = message;
  
  // Add to top of page
  document.body.insertBefore(messageDiv, document.body.firstChild);
  
  // Optional: Auto-hide after 5 seconds
  setTimeout(() => {
    messageDiv.remove();
  }, 5000);
}

Testing Your Integration

Test Scenarios

  1. Successful Login: Create a valid JWT and verify the user is logged in successfully
  2. Email Verification Skip: Use emailVerified: true and confirm no email verification step
  3. Email Verification Required: Omit emailVerified and confirm email verification is required
  4. Account Not Found: Test with an email not in the system and verify ?error=account-not-found redirect
  5. Account Disabled: Test with a disabled account and verify ?error=account-disabled redirect
  6. SSO Email Verification: Test email verification flow and verify ?error=email-verification-required redirect
  7. Invalid JWT: Test with expired/invalid tokens and verify appropriate error handling

Debugging

  • Check JWT claims: Ensure all required claims are present and valid
  • Verify signatures: Confirm JWT is signed with the correct CLIENTSECRET
  • Monitor redirects: Check that error redirects include the expected error parameters
  • Test token expiry: Ensure tokens are not expired when submitted

Security Notes

  • Ensure the JWT includes all required claims, and the exp claim is no more than 5 minutes in the future.
  • The iat claim must not be more than 30 seconds in the past.
  • Use HTTPS for all communication to secure data in transit.
  • Store the CLIENTSECRET securely and never expose it publicly.
  • Email Verification Security: Only set emailVerified: true for emails you have actually verified in your system.
  • Error Handling: Implement proper error handling on your Remote Login URL to provide good user experience.

Migration Guide for Existing Integrations

If you have an existing JWT SSO integration:

  • No changes required - Your current integration will continue to work exactly as before
  • To add email verification: Simply add the emailVerified claim to your JWT payload when the user's email is verified
  • To improve error handling: Update your Remote Login URL to handle the new human-readable error parameters

Support and Troubleshooting

If you encounter issues:

  1. Validate your JWT: Use tools like jwt.io to decode and verify your token structure
  2. Check server logs: Look for JWT validation errors in your application logs
  3. Test incrementally: Start with basic authentication, then add email verification features
  4. Contact support: Include example JWT payload (without secrets) when requesting assistance

By following these steps, you can successfully configure and use JWT SSO with Benji Pays to provide a seamless, secure authentication experience for your users.

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article