Overview

Integrating custom Microsoft Entra ID (Azure AD) authentication with an Azure Static Web App (SWA) on the Standard tier should be straightforward, but subtle misconfigurations can lead to a frustrating infinite redirect loop.

Typically, you log in, complete MFA, and watch the browser bounce repeatedly between Entra ID and your application until Microsoft halts the flow with Error 50074 (“We couldn’t sign you in”). When you check /.auth/me, you find that clientPrincipal is null.

Azure Static Web Apps Login Redirects: How to Stop It
Azure Static Web Apps Login Redirects: How to Stop It

Here is a breakdown of why this happens and the exact checklist to fix it.


The Problem: Why Does the App Loop?

The infinite loop occurs when the interactive user login succeeds in Entra ID, but SWA’s backend proxy fails the subsequent token exchange.

When the token exchange fails: 1. SWA cannot establish the StaticWebAppsAuthCookie. 2. The user lands back on the app unauthenticated (clientPrincipal: null). 3. SWA evaluates the catch-all route guard (/*), issues a 401, and responseOverrides immediately redirects the user back to /.auth/login/aad. 4. The cycle repeats until Entra ID detects the loop and blocks access.

Two common triggers for this failure are explicitly passing OAuth parameters (like response_type=code or scope) inside login.loginParameters—which breaks SWA’s built-in token negotiation—and using internal rewrite rules instead of explicit redirect routes.


What to Check


Working staticwebapp.config.json Baseline

Use this base configuration to validate that the login process works properly. You can then make additional changes for your configuration.

{
  "auth": {
    "identityProviders": {
      "azureActiveDirectory": {
        "registration": {
          "openIdIssuer": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
          "clientIdSettingName": "AZURE_CLIENT_ID",
          "clientSecretSettingName": "AZURE_CLIENT_SECRET"
        }
      }
    }
  },
  "routes": [
    {
      "route": "/login",
      "redirect": "/.auth/login/aad?post_login_redirect_uri=/",
      "statusCode": 302
    },
    {
      "route": "/logout",
      "redirect": "/.auth/logout?post_logout_redirect_uri=/",
      "statusCode": 302
    },
    {
      "route": "/*",
      "allowedRoles": ["authenticated"]
    }
  ],
  "responseOverrides": {
    "401": {
      "redirect": "/.auth/login/aad?post_login_redirect_uri=/",
      "statusCode": 302
    }
  }
}


🌟 Let’s Connect & Build Together

Thanks for reading! 😊 If you enjoyed these resources, let’s stay in touch! I share deep-dives into AI/ML patterns and host community events here:

👉 Originally published at ozkary.com