0

As per below code I am able to successfully log in and obtain an access token. However, when I make a request to the https://login.microsoftonline.com/{tenant-id}/openid/userinfo API at runtime, I encounter a CORS error.

My code is as follows:

import React, { useEffect, useState } from 'react';
import { OidcClient } from 'oidc-client';

const LoginButton = () => {
  const [user, setUser] = useState(null);

  const handleLogin = async () => {
    const config = {
      authority: 'https://login.microsoftonline.com/{tenant-id}',
      client_id: '{app-id}',
      redirect_uri: 'http://localhost:3000',
      response_type: 'code',
      scope: 'openid profile user.read',
    };

    const userManager = new OidcClient(config);
    const state = { nonce: generateNonce() };
    const request = await userManager.createSigninRequest({ state });

    saveState(state); // Persist the state to storage

    window.location.href = request.url;
  };

  useEffect(() => {
    const processCallback = async () => {
      const urlParams = new URLSearchParams(window.location.search);
      const code = urlParams.get('code');
      const savedState = getState(); // Retrieve the state from storage

      if (code && savedState) {
        const config = {
          authority: 'https://login.microsoftonline.com/{tenant-id}',
          client_id: '{app-id}',
          redirect_uri: "http://localhost:3000",
          response_type: 'code',
          scope: 'openid profile',
        };

        const userManager = new OidcClient(config);

        const response = await userManager.processSigninResponse();
        const userProfile = await userManager.getUser();

        setUser(userProfile);
        clearState(); // Clear the state from storage after successful authentication
      }
    };

    processCallback();
  }, []);

  const generateNonce = () => {
    // Implement your nonce generation logic here
    // For example, you can use a random string generator library
    return 'generated-nonce';
  };

  const saveState = (state) => {
    localStorage.setItem('authState', JSON.stringify(state));
  };

  const getState = () => {
    const savedState = localStorage.getItem('authState');
    return savedState ? JSON.parse(savedState) : null;
  };

  const clearState = () => {
    localStorage.removeItem('authState');
  };

  return (
    <div>
      {user && user.profile ? (
        <>
          <p>Welcome, {user.profile.given_name}!</p>
          <p>Access Token: {user.access_token}</p>
        </>
      ) : (
        <button onClick={handleLogin}>Login</button>
      )}
    </div>
  );
};

export default LoginButton;

What's wrong in the above code or I did mistake in AzureAD app. why CORS error occurring, I did any mistake in code want to understand what is my mistake. Also attached the screenshot for reference.

enter image description here

1 Answers1

0

Note that, you need to have token generated with v1 endpoint to make request for https://login.microsoftonline.com/{tenant-id}/openid/userinfo API

I registered one Azure AD application and added API permissions as below:

enter image description here

I ran below authorization request in browser and got code in address bar like this:

https://login.microsoftonline.com/<tenantID>/oauth2/authorize?
client_id=<appID>
&scope=openid profile user.read
&redirect_uri=http://localhost:3000
&response_type=code

Response:

enter image description here

Now, I generated access token using authorization code flow via Postman with below parameters:

POST https://login.microsoftonline.com/<tenantID>/oauth2/token
grant_type:authorization_code
client_id:appID
client_secret:secret
code:<code_from_above_Step>
redirect_uri: http://localhost:3000

Response:

enter image description here

When I used this access token to call /userinfo endpoint, I got response successfully like below:

GET https://login.microsoftonline.com/{tenant-id}/openid/userinfo
Authorization: Bearer <access_token_from_above_step>

Response:

enter image description here

If you generated access token using v2 endpoint, you need to use below /userinfo endpoint:

GET https://graph.microsoft.com/oidc/userinfo
Authorization: Bearer <access_token_from_above_step>

In your case, decode your access token in jwt.ms and check aud claim.

If it is 00000003-0000-0000-c000-000000000000, you need to use Microsoft Graph /userinfo endpoint.

You can also run /me endpoint by including MS Graph token to get signed-in user information like below:

GET https://graph.microsoft.com/v1.0/me
Authorization: Bearer <access_token_from_above_step>

Response:

enter image description here

Reference:

Azure AD UserInfo endpoint | Azure Active Directory by Barbaraa Castilho [MSFT]

openid - Azure AD metadata and userinfo does not support CORS - Stack Overflow by Saca

Sridevi
  • 10,599
  • 1
  • 4
  • 17