Authentication and Authorization in Azure

Authentication and Authorization 
in Azure


    OAuth 2.0, OpenID Connect, and Microsoft Entra ID work together to provide modern identity, authentication, and authorization services across the web. OAuth 2.0 handles authorization (what a user can access), OpenID Connect adds authentication (who the user is, for app access), and MS Entra ID acts as the Identity Provider (IdP) that issues the secure tokens for both. MS Entra Id was formerly Azure Active Directory.

     Register your app in the MS Entra admin center. This generates a unique Client Id, registers your Redirect URIs, and defines what API permissions (scopes) your app needs.

     Steps: 1) Request, 2) Redirection, 3) Authentication, 4) ID or Access Token Issued.

     The caller is the one that must invoke MS Auth Library’s (MSAL) AcquireTokenSilent method. The caller handles token acquisition errors raising UiRequiredAuthError (and pops up login screen), while the target API handles token validation errors raising HTTP 401 Unauthorized or HTTP 403 Forbidden. Your app must check for Access Token on every single API call. Everyone implements this by using a HTTP Interceptor pattern (such as Axios Interceptor, a native fetch interceptor, or Angular's HTTP_INTERCEPTOR) that is called every time. Instead, the Interceptor sits invisibly between your application code and the network library (like fetch, Axios, or Angular’s HttpClient). The common Interceptor does: 1. Runs AcquireTokenSilent() 2. Try/Catches UiRequiredAuthError -> Triggers Login UI  3. Appends "Bearer <token>" to HTTP headers.  

The HTTP packet runs over the wire like:
   GET /api/v1/data HTTP/1.1
   Host: ://yourservice.com
   Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im...

Typescript Native Fetch Interceptor:
import { PublicClientApplication } from '@azure/msal-browser';
const msalInstance = new PublicClientApplication({ /* config */ });

// A universal wrapper function replacing standard 'fetch'
export async function secureFetch(url: string, options: RequestInit = {}) {
  try {
    const account = msalInstance.getActiveAccount();
    const tokenResponse = await msalInstance.acquireTokenSilent({
      scopes: ['api://your-api-id/access_as_user'],
      account: account || undefined
    });

    // Ensure headers object exists
    options.headers = {
      ...options.headers,
      'Authorization': `Bearer ${tokenResponse.accessToken}`,
      'Content-Type': 'application/json'
    };
  } catch (error) {
    if (error.name === "InteractionRequiredAuthError") {
      return msalInstance.acquireTokenRedirect({ scopes: ['api://your-api-id/access_as_user'] });
    }
    throw error;
  }

  // Execute the target fetch method with the injected auth headers
  return fetch(url, options);
}

How they use it (in Typescript):
import { secureFetch } from './secureFetch';

async function updateProfile(userId, data) {
  // Target API and method (POST) are cleanly managed natively
  const response = await secureFetch(`/api/users/${userId}`, {
    method: 'POST',
    body: JSON.stringify(data)
  });
  return response.json();
}


Comments

Popular posts from this blog

GHL Email Campaigns

Await

Whitelabel Options