How to authenticate users with Entra ID OAuth2.0 flow in a React Native App

Young, Charles 5 Reputation points
2023-10-16T03:20:12.7333333+00:00

Hello,

I am trying to authenticate users using OAuth2.0 in a cross-platform React Native (expo) app by using Entra ID's app registration feature. In the future I hope to have the app access data in an Azure SQL database, but I need to authenticate users first. I am very new to backend development and Azure services.

I have configured the app registration as a 'Mobile and Desktop App' using the URI [http://localhost:8081/auth]

So far I can get an authorization code, but I can not exchange it for an access token.

Here is the relevant code in my app:

const [discovery, $discovery]: any = useState({});
  const [authRequest, $authRequest]: any = useState({});
  const [authorizeResult, $authorizeResult]: any = useState({});
  const scopes = ["openid", "profile", "email", "offline_access"];
  const domain = `https://login.microsoftonline.com/${ADConfig.directoryTenantID}/v2.0`;
  const redirectUrl = AuthSession.makeRedirectUri({ path: "auth" });

  const getSession = async () => {
    const d = await AuthSession.fetchDiscoveryAsync(domain);

    const authRequestOptions: AuthSession.AuthRequestConfig = {
      prompt: AuthSession.Prompt.Login,
      responseType: AuthSession.ResponseType.Code,
      scopes: scopes,
      usePKCE: true,
      clientId: ADConfig.applicationClientID,
      //clientSecret: ADConfig.secretValue,
      redirectUri: __DEV__ ? redirectUrl : redirectUrl + "example",
      state: ADConfig.state,
    };
    const authRequest = new AuthSession.AuthRequest(authRequestOptions);
    $authRequest(authRequest);
    $discovery(d);
  };

  const getCodeExchange = async () => {
    const tokenResult = await AuthSession.exchangeCodeAsync(
      {
        code: authorizeResult.params.code,
        clientId: ADConfig.applicationClientID,
        redirectUri: __DEV__ ? redirectUrl : redirectUrl + "example",

        extraParams: {
          code_verifier: authRequest.codeVerifier || "",
          grant_type: "authorization_code",
          //client_secret: ADConfig.secretValue,
        },
      },
      discovery
    );
    const { accessToken, refreshToken, issuedAt, expiresIn } = tokenResult;

    console.log(accessToken, refreshToken, issuedAt, expiresIn);
  };

The following error is thrown when trying to get an access token enter image description here enter image description here

I'm not trying to make a SPA, but I guess this flow is for SPAs? I can't find what I should change to authenticate for a public client like a mobile/cross-platform app.

Any guidance would be appreciated! I get the feeling I may be on the wrong path entirely

I found the Entra ID React Native example to be unhelpful because react-native-app-auth is not expo compatible. I am using expo-auth-session like this example

Microsoft Security Microsoft Entra Microsoft Entra ID
Microsoft Security Microsoft Entra Other
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Navya 19,795 Reputation points Microsoft External Staff Moderator
    2023-10-17T08:46:49.87+00:00

    Hi @Young, Charles , thanks for reaching us.

    I Understand you are trying to authenticate users using OAuth2.0 in a cross-platform React Native (expo) app by using Entra ID's app registration feature. You have configured the app registration as a 'Mobile and Desktop App' using the URI [http://localhost:8081/auth]. you can get an authorization code, but you cannot exchange it for an access token.

    Authorization code flow is a protocol that enables a client application to obtain authorized access to protected resources like web APIs. The auth code flow requires a user-agent that supports redirection from the authorization server back to your application, PKCE adds an additional layer of security to the authorization code flow by requiring the client to generate a code challenge and a code verifier which aims to prevent interception attacks on public clients as they do not have a secret which means they do not have a real way of authenticating themselves.

    You have configured the app registration as a 'Mobile and Desktop App' platform for this PKCE is not required it is recommended. Other hand PKCE is required for Single-Page-Application (SPA)

    Yes, you are using SPA flow code, but you didn't mention PKCE parameters in your code: code_verifier & code_challengemethod. These two parameters are required when you set usePKCE as true.

    For your reference: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow

    As you mention you are not trying to make SPA, could you confirm why you are not making SPA?

    If you want to authenticate for a public client like a mobile/cross-platform app PKCE is recommended as they have less security.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.