Advanced Portal Designer Documentation
Index

External Authentication

APD supports integration with external identity providers for single sign-on (SSO) and enhanced authentication options.

Supported Providers

Auth0

Auth0 is a flexible authentication platform supporting:

  • Username/password login
  • Social logins (Google, Facebook, etc.)
  • Multi-factor authentication
  • Enterprise connections

Microsoft Entra ID (Azure AD)

Microsoft's identity platform for:

  • Enterprise SSO
  • Azure AD B2C for consumers
  • Microsoft account login
  • Conditional access policies

Auth0 Integration

Prerequisites

  1. Auth0 account and tenant
  2. Auth0 application configured
  3. APD Setup configured with Auth0 settings

Configuration

Auth0 Tenant Setup

  1. Create Auth0 application (Regular Web App)
  2. Configure callback URLs
  3. Note Client ID and Client Secret

APD Setup

  1. Open the Advanced Portal Designer menu page (search for it in Tell Me)
  2. Open the 3rd Party Auth Setup page (the APD Auth0 Setup Hgd table — accessed via the menu)
  3. Fill in the Auth0 fields: Auth0 Domain, Auth0 Client Id (Client Id), Auth0 Client Secret (Client Secret), Auth0 Login Authorize Redirect, Auth0 Login Complete Redirect

Auth0 Login Flow

┌──────────────┐
│ User clicks  │
│ Login        │
└──────┬───────┘
       ▼
┌──────────────┐
│ Redirect to  │
│ Auth0        │
└──────┬───────┘
       ▼
┌──────────────┐
│ User         │
│ authenticates│
└──────┬───────┘
       ▼
┌──────────────┐
│ Auth0 returns│
│ with token   │
└──────┬───────┘
       ▼
┌──────────────┐
│ APD validates│
│ token        │
└──────┬───────┘
       ▼
┌──────────────┐
│ Create/link  │
│ APD user     │
└──────┬───────┘
       ▼
┌──────────────┐
│ Session      │
│ established  │
└──────────────┘

Use the Auth0 login URL in your template:

<a href="<?auth0link?>">Login with Auth0</a>

To force unauthenticated users into the Auth0 flow, configure your Auth0 login as the Login Action in APD Setup. APD then redirects unauthenticated requests to that action automatically — there is no <?redirect?> template tag.

Auth0 Logout

<a href="<?auth0logoutlink?>">Logout</a>

Microsoft Entra ID Integration

Prerequisites

  1. Azure subscription
  2. Entra ID tenant (Azure AD)
  3. App registration in Azure

Azure Configuration

App Registration

  1. Go to Azure Portal > Entra ID > App Registrations
  2. Create new registration
  3. Configure:
    • Redirect URIs
    • API permissions
    • Client secret or certificate

Required Permissions

  • openid
  • profile
  • email

APD Configuration

  1. Open the Advanced Portal Designer menu page (search for it in Tell Me)
  2. Open the 3rd Party Auth Setup page (the APD Auth0 Setup Hgd table also stores the Entra fields)
  3. Fill in: Entra Domain (Tenant Name), Entra TenantId, Entra Client Id, Entra Client Secret, Entra Login Authorize Redirect, Entra Login Complete Redirect

Entra ID Login Flow

Similar to Auth0:

  1. User redirected to Microsoft login
  2. User authenticates with Microsoft account
  3. Microsoft returns authorization code
  4. APD exchanges code for tokens
  5. APD validates and creates session
<a href="<?entralink?>">Login with Microsoft</a>

User Mapping and Not Mapped Flow

Automatic User Creation

When an external user authenticates for the first time:

  1. APD receives identity token from Auth0/Entra
  2. APD checks for existing user by External ID
  3. If not found, APD creates new user:
- User ID: External identifier (e.g., `ENTRA abc-123-def`)
  • Name: From identity token
  • Email: From identity token
  • External User: Set to Auth0 or Microsoft Entra
  • External ID: Provider's unique identifier
  • Not Mapped: Set to Yes
  1. APD checks for matching invitation by email/domain
  2. If invitation found, applies settings
  3. User is authenticated but may be not mapped

The Not Mapped State

New external users are marked Not Mapped because:

  • They have no Business Central entity link
  • The NAV Identification field is blank
  • Security filters using %4 placeholder won't work

What happens to not-mapped users:

  1. User successfully authenticates
  2. APD detects Not Mapped = Yes
  3. User redirected to the Not Mapped Action
  4. User stays on Not Mapped Action until mapped

Setting Up Not Mapped Action

You must create an action to handle not-mapped users:

  1. Create a new action (e.g., ACCOUNT-SETUP)
  2. Set Not Mapped Action = Yes
  3. Create template to collect/display mapping info

Important: If no Not Mapped Action exists, APD will show an error:

"No action defined for 'Not Mapped' users, cannot continue"

Not Mapped Template Options

Option 1: Self-Service Mapping

<h1>Complete Your Registration</h1>
<p>Hello <?userid?>, please enter your customer number:</p>

<form method="post">
    <input type="text" name="customerno" placeholder="Customer No.">
    <button type="submit">Submit</button>
</form>

Option 2: Pending Approval

<h1>Registration Pending</h1>
<p>Thank you for registering, <?userid?>.</p>
<p>Your account is pending administrator approval.</p>
<p>You will receive an email when your account is activated.</p>

Option 3: Contact Information

<h1>Additional Information Required</h1>
<p>Welcome, <?userid?>!</p>
<p>Please contact us to complete your account setup:</p>
<ul>
    <li>Email: support@company.com</li>
    <li>Phone: 555-1234</li>
</ul>

Clearing Not Mapped Status

The Not Mapped flag clears automatically when NAV Identification is set:

Via Admin:

  1. Open APD Users in BC
  2. Find the user
  3. Set BC Type (Customer, Vendor, etc.)
  4. Set BC Number (Customer No., etc.)
  5. Not Mapped clears automatically

Via Script Action:

// In script action handling self-service mapping
User.Get(Session.UserID);
User."User Type" := User."User Type"::Customer;
User."NAV Identification" := CustomerNo;
User.Modify();

Invitation Integration

Invitations can pre-configure external users by email domain:

Invitation Type: E-mail domain
Invitation Value: contoso.com
Company: CRONUS
Security Filters: CUSTOMER
Navision Type: Customer

When a user with @contoso.com email authenticates:

  • Company set to CRONUS
  • Security profile CUSTOMER assigned
  • BC Type set to Customer
  • User still needs NAV Identification (Customer No.)

See Invitations

Manual Pre-Mapping

Pre-create users to avoid Not Mapped state:

  1. In APD Users, create user with expected External ID
  2. Set BC Type and BC Number
  3. When user authenticates, they're already mapped

Finding the External ID:

- Auth0: The sub claim (e.g., `auth0 1234567890`)
- Entra: `ENTRA + Object ID (e.g., ENTRA abc-123-def-456`)

Hybrid Authentication

Supporting Multiple Methods

Allow both local and external login:

<div class="login-options">
    <div class="local-login">
        <h3>Login with credentials</h3>
        <form method="post">
            <input type="text" name="username" placeholder="Username">
            <input type="password" name="password" placeholder="Password">
            <button type="submit">Login</button>
        </form>
    </div>
    
    <div class="divider">or</div>
    
    <div class="external-login">
        <h3>Login with external account</h3>
        <a href="<?auth0link?>" class="btn-auth0">
            Login with Auth0
        </a>
        <a href="<?entralink?>" class="btn-microsoft">
            Login with Microsoft
        </a>
    </div>
</div>

Token Handling

Access Tokens

External auth provides access tokens:

  • Stored in session
  • Used for API calls if needed
  • Have expiration time

Refresh Tokens

For long-lived sessions:

  • Stored securely
  • Used to get new access tokens
  • Handle token refresh automatically

Security Considerations

HTTPS Required

Always use HTTPS for:

  • Login pages
  • Callback URLs
  • Token exchange

Token Validation

APD validates tokens:

  • Signature verification
  • Expiration check
  • Audience validation
  • Issuer validation

Session Handling

After external auth:

  • APD creates local session
  • Session timeout applies
  • Logout clears both local and external session

Error Handling

Auth Failures

<!-- <?loginerror?> returns empty when no error is set, so no <?if?> guard is needed -->
<div class="alert alert-danger error-empty-hide">
    Authentication failed: <?loginerror(.)?>
</div>

Common Errors

Error Cause Solution
Invalid redirect Callback URL mismatch Check app configuration
Token expired Session timeout Re-authenticate
User not found No matching email Create user or invitation
Invalid client Wrong client ID/secret Verify APD settings

Debugging

Test External Auth

  1. Configure staging environment
  2. Use test accounts
  3. Check callback URL handling
  4. Verify user creation/linking

Logging

Monitor authentication events:

  • Login attempts
  • Token exchanges
  • User creation
  • Errors

Best Practices

Security

  • Use HTTPS everywhere
  • Validate all tokens
  • Handle errors gracefully
  • Log authentication events

User Experience

  • Clear login options
  • Handle errors nicely
  • Support password reset
  • Remember user preference

Maintenance

  • Monitor for issues
  • Update secrets regularly
  • Review user mappings
  • Test after provider updates