AzureAD / microsoft-authentication-library-for-js

Microsoft Authentication Library (MSAL) for JS
http://aka.ms/aadv2
MIT License
3.68k stars 2.65k forks source link

msalInstance.acquireTokenByCode not working #7425

Open denghejun opened 1 day ago

denghejun commented 1 day ago

Core Library

MSAL.js (@azure/msal-browser)

Core Library Version

3.27.0

Wrapper Library

MSAL React (@azure/msal-react)

Wrapper Library Version

2.2.0

Public or Confidential Client?

Public

Description

const tokenResponse = await msalInstance.acquireTokenByCode({ code: payload.code, scopes: [ "user.read" ], redirectUri: "https://xxx/oauth/aad/callback", redirect_url: "https://xxx/oauth/aad/callback", redirectUrl: "https://xxx/oauth/aad/callback" });

Error Message

erverError: invalid_grant: Error(s): 700009 - Timestamp: 2024-11-18 08:19:26Z - Description: AADSTS700009: Reply address must be provided when presenting an authorization code requested with an explicit reply address. Trace ID: bb8fc0ba-128b-47f5-8990-4f9beaff2c00 Correlation ID: 01933e5a-ec11-71cf-97ff-814e82630d82 Timestamp: 2024-11-18 08:19:26Z - Correlation ID: 01933e5a-ec11-71cf-97ff-814e82630d82 - Trace ID: bb8fc0ba-128b-47f5-8990-4f9beaff2c00

MSAL Logs

No response

Network Trace (Preferrably Fiddler)

MSAL Configuration

const msalInstance = await msal.createStandardPublicClientApplication({
    auth: {
        clientId: "FAKE_1", // use fake one here, please ignore
        authority: "FAKE_2",
        redirectUri: "https://xxx/oauth/aad/callback"
    },
});

Relevant Code Snippets

const tokenResponse = await msalInstance.acquireTokenByCode({
            code: payload.code,
            scopes: [ "user.read" ],
            redirectUri: "https://xxx/oauth/aad/callback",
            redirect_url: "https://xxx/oauth/aad/callback",
            redirectUrl: "https://xxx/oauth/aad/callback"
        });

Reproduction Steps

as the code desc

Expected Behavior

get token success

Identity Provider

Entra ID (formerly Azure AD) / MSA

Browsers Affected (Select all that apply)

Chrome, Firefox, Edge, Safari, Other

Regression

NA

denghejun commented 1 day ago

always got "AADSTS700009: Reply address must be provided when presenting an authorization code requested with an explicit reply address", even I already gave a lots of redirectUrl/uri .... ...

LuccaRebelloToledo commented 22 hours ago

You can try this:

https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/acquire-token.md

denghejun commented 13 hours ago

I tried them all, failed

LuccaRebelloToledo commented 13 hours ago

I tried them all, failed

Do you've same error?

Can you share your actually code(like components, imports)?

denghejun commented 11 hours ago
import * as msal from "@azure/msal-browser";
import {EventType} from "@azure/msal-browser";

const msalInstance = await msal.createStandardPublicClientApplication({
    auth: {
        clientId: "MASK_MASK",
        authority: "https://login.microsoftonline.com/MASK_MASK",
        redirectUri: "https://localhost:3000/oauth/aad/callback"
    },
});

export const ssoSignIn = async () => {
    try {
        await msalInstance.initialize()
        const loginResponse = await msalInstance.loginRedirect({
            scopes: ["user.read"],
        });

        if(!msalInstance.getActiveAccount() && msalInstance.getAllAccounts().length>0) {
            msalInstance.setActiveAccount(msalInstance.getAllAccounts()[0]);
        }

        msalInstance.enableAccountStorageEvents();
        msalInstance.addEventCallback((event)=>{
            if(event.eventType === EventType.LOGIN_SUCCESS || event.eventType === EventType.ACQUIRE_TOKEN_SUCCESS || event.eventType===EventType.SSO_SILENT_SUCCESS) {
                const account = event.payload.account;
                msalInstance.setActiveAccount(account);
            }
        })
    } catch (err) {
        console.log("SSO sign-in failed")
        console.log(err)
    }
};

export const getSignInUserInfo = async (payload) => {
    try {
        console.log("starting get AAD access token...")
        console.log("Code is :")
        console.log(payload) // Got code successfully here, payload.code

        // Got Error here, same error, always
        const tokenResponse = await msalInstance.acquireTokenByCode({
            code: payload.code,
            scopes: [ "user.read" ],
            redirect_uri: "https://localhost:3000/oauth/aad/callback",
            enableSpaAuthorizationCode: true,
            tokenQueryParameters: {
                redirect_uri: "https://localhost:3000/oauth/aad/callback",
        },
    });

        console.log("Get access token successfully: ")
        console.log(tokenResponse.accessToken)
        console.log("Starting get user detail info")
        var headers = new Headers();
        var bearer = "Bearer " + tokenResponse.accessToken;
        console.log("bearer header is")
        console.log(bearer)
        headers.append("Authorization", bearer);
        var options = {
            method: "GET",
            headers: headers
        };

        var graphEndpoint = "https://graph.microsoft.com/v1.0/me";
        const resp = await fetch(graphEndpoint, options);
        console.log(`Get user info success: ${resp}`)
        return resp;
    } catch (error) {
        console.log("AAD login failed:") // will delete after testing
        console.log(error)
        return {status: 500, message: "Internal Server Error"};
    }
};

Steps:

  1. call ssoSignIn will login success and redirect to redirect-uri with code successfully
  2. call getSignInUserInfo under 'redirect-uri' route, successfully got the code from the redirect uri, but got error when using the code to acquire token
denghejun commented 8 hours ago

then now, I'm getting this error:

ServerError: invalid_grant: Error(s): 501481 - Timestamp: 2024-11-19 06:37:42Z - Description: AADSTS501481: The Code_Verifier does not match the code_challenge supplied in the authorization request. Trace ID: 4bb5c77a-3089-44af-9e5e-6620fd571000 Correlation ID: 01934324-235e-7101-8e6a-8bc95899ac2a Timestamp: 2024-11-19 06:37:42Z - Correlation ID: 01934324-235e-7101-8e6a-8bc95899ac2a - Trace ID: 4bb5c77a-3089-44af-9e5e-6620fd571000

LuccaRebelloToledo commented 2 hours ago

then now, I'm getting this error:

ServerError: invalid_grant: Error(s): 501481 - Timestamp: 2024-11-19 06:37:42Z - Description: AADSTS501481: The Code_Verifier does not match the code_challenge supplied in the authorization request. Trace ID: 4bb5c77a-3089-44af-9e5e-6620fd571000 Correlation ID: 01934324-235e-7101-8e6a-8bc95899ac2a Timestamp: 2024-11-19 06:37:42Z - Correlation ID: 01934324-235e-7101-8e6a-8bc95899ac2a - Trace ID: 4bb5c77a-3089-44af-9e5e-6620fd571000

This error is about your code verifier.

LuccaRebelloToledo commented 2 hours ago
import * as msal from "@azure/msal-browser";
import {EventType} from "@azure/msal-browser";

const msalInstance = await msal.createStandardPublicClientApplication({
    auth: {
        clientId: "MASK_MASK",
        authority: "https://login.microsoftonline.com/MASK_MASK",
        redirectUri: "https://localhost:3000/oauth/aad/callback"
    },
});

export const ssoSignIn = async () => {
    try {
        await msalInstance.initialize()
        const loginResponse = await msalInstance.loginRedirect({
            scopes: ["user.read"],
        });

        if(!msalInstance.getActiveAccount() && msalInstance.getAllAccounts().length>0) {
            msalInstance.setActiveAccount(msalInstance.getAllAccounts()[0]);
        }

        msalInstance.enableAccountStorageEvents();
        msalInstance.addEventCallback((event)=>{
            if(event.eventType === EventType.LOGIN_SUCCESS || event.eventType === EventType.ACQUIRE_TOKEN_SUCCESS || event.eventType===EventType.SSO_SILENT_SUCCESS) {
                const account = event.payload.account;
                msalInstance.setActiveAccount(account);
            }
        })
    } catch (err) {
        console.log("SSO sign-in failed")
        console.log(err)
    }
};

export const getSignInUserInfo = async (payload) => {
    try {
        console.log("starting get AAD access token...")
        console.log("Code is :")
        console.log(payload) // Got code successfully here, payload.code

        // Got Error here, same error, always
        const tokenResponse = await msalInstance.acquireTokenByCode({
            code: payload.code,
            scopes: [ "user.read" ],
            redirect_uri: "https://localhost:3000/oauth/aad/callback",
            enableSpaAuthorizationCode: true,
            tokenQueryParameters: {
                redirect_uri: "https://localhost:3000/oauth/aad/callback",
        },
    });

        console.log("Get access token successfully: ")
        console.log(tokenResponse.accessToken)
        console.log("Starting get user detail info")
        var headers = new Headers();
        var bearer = "Bearer " + tokenResponse.accessToken;
        console.log("bearer header is")
        console.log(bearer)
        headers.append("Authorization", bearer);
        var options = {
            method: "GET",
            headers: headers
        };

        var graphEndpoint = "https://graph.microsoft.com/v1.0/me";
        const resp = await fetch(graphEndpoint, options);
        console.log(`Get user info success: ${resp}`)
        return resp;
    } catch (error) {
        console.log("AAD login failed:") // will delete after testing
        console.log(error)
        return {status: 500, message: "Internal Server Error"};
    }
};

Steps:

  1. call ssoSignIn will login success and redirect to redirect-uri with code successfully
  2. call getSignInUserInfo under 'redirect-uri' route, successfully got the code from the redirect uri, but got error when using the code to acquire token

I will try on my computer and get back to you with feedback.

LuccaRebelloToledo commented 1 hour ago
import { AuthenticationResult, Configuration, EventMessage, EventType, PopupRequest, PublicClientApplication } from "@azure/msal-browser";
import { useMsal } from "@azure/msal-react";

export const msalConfig: Configuration = {
  auth: {
      clientId: "MASK_MASK",
      authority: "https://login.microsoftonline.com/MASK_MASK",
      redirectUri: "https://localhost:3000/oauth/aad/callback",
      postLogoutRedirectUri: "/"
  },
  system: {
      allowNativeBroker: false // Disables WAM Broker
  }
};

export const loginRequest: PopupRequest = {
  scopes: ["User.Read"]
};

const graphEndpoint = "https://graph.microsoft.com/v1.0/me";

const msalInstance = new PublicClientApplication(msalConfig);

// Account selection logic is app dependent. Adjust as needed for different use cases.
export const ssoSignIn = async () => {
    try {
        await msalInstance.initialize();

        const accounts = msalInstance.getAllAccounts();

        if (accounts.length > 0) {
            msalInstance.setActiveAccount(accounts[0]);
        }

        msalInstance.addEventCallback((event: EventMessage) => {
            if (event.eventType === EventType.LOGIN_SUCCESS && event.payload) {
                const payload = event.payload as AuthenticationResult;
                const account = payload.account;
                msalInstance.setActiveAccount(account);
            }
        });

        if (!msalInstance.getActiveAccount() && msalInstance.getAllAccounts().length > 0) {
          msalInstance.setActiveAccount(msalInstance.getAllAccounts()[0]);
        }

      //   const root = ReactDOM.createRoot(
      //     document.getElementById("root") as HTMLElement
      // );
      // root.render(
      //     <Router>
      //        <App pca={msalInstance} />
      //     </Router>
      // );
    } catch (err) {
        console.log("SSO sign-in failed")
        console.log(err)
    }
};

export const redirectSignIn = async () => {
  const { instance } = useMsal();

  instance.loginRedirect(loginRequest);

  // View this sample: samples\msal-react-samples\typescript-sample\src\ui-components\SignInButton.tsx
}

export const getSignInUserInfo = async () => {
  try {
    const account = msalInstance.getActiveAccount();

    if (!account) {
        throw Error("No active account! Verify a user has been signed in and setActiveAccount has been called.");
    }

    const response = await msalInstance.acquireTokenSilent({
        ...loginRequest,
        account
    });

    const headers = new Headers();
    const bearer = `Bearer ${response.accessToken}`;

    headers.append("Authorization", bearer);

    const options = {
        method: "GET",
        headers: headers
    };

    const res = await fetch(graphEndpoint, options);
    console.log(`Get user info success: ${res}`);
    return res.json();
  } catch(error) {
    console.log(error)
  }
}

I believe it may just be the flow you are following, I made some changes, I haven't tested them but, it may give you some light to continue your development.

The code examples are at:

microsoft-authentication-library-for-js/samples/msal-react-samples/typescript-sample