Azure Identity SDK (JS) How to Authenticate to User's Azure Account

alma eyre 11 Reputation points
2022-02-06T23:43:58.273+00:00

I am designing my first dev tool with the Azure SDK (JavaScript), and I am having a difficult time understanding how to authenticate users in production so the dev tool can access the user's Azure account. The tool is going to retrieve metrics from all of the user's Azure Functions in their tenant to display React component graphs based on those metrics over time. The app will be run locally with an npm run command.

My entry point for using Azure Identity in my app was this blog post (https://devblogs.microsoft.com/azure-sdk/authentication-and-the-azure-sdk/). I like the way the DefaultAzureCredential is working in development, using the tenant for whichever developer is running it by using the AzureCliCredential. I want a similar functionality for production, but for the browser instead of Azure Cli. In other words, if a user is already logged in to Azure Portal, it will get a credential for their tenant. How do I go about this?

One of the things I tried was opting into the Interactive Browser of the DefaultAzureCredential as described in that blog post. But even though, I could see the browser method in the src (https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/src/credentials/defaultAzureCredential.browser.ts), I couldn't figure how to opt into this when using the actual SDK. I couldn't find that method in the npm package in Azure Identity, and the documentation (https://learn.microsoft.com/en-us/javascript/api/@azure/identity/defaultazurecredentialoptions?view=azure-node-latest) didn't help me either. If this is the correct option for my use case, I would like to understand how to opt into it and use it.

Another thing I tried was implementing the InteractiveBrowserCredential. As long as I pass in a redirectUri with a port not already being used by my app, it did open another tab to tell me to login to the Azure Portal if I am not already logged in. This is exactly the user experience I would want in my app. However, after logging in the credential didn't actually do anything. The credential returned actually has a client Id equal to the application Id (04b07795-8ddb-461a-bbee-02f9e1bf7b46) of Azure CLI (https://learn.microsoft.com/en-us/troubleshoot/azure/active-directory/verify-first-party-apps-sign-in) for some reason. This led me to look into the Interactive Browser Credential and find out that it is using the Authorization Code Flow (https://learn.microsoft.com/en-us/javascript/api/@azure/identity/interactivebrowsercredential?view=azure-node-latest). This flow doesn't seem right for my use case, since I have to register my app. I am not trying to grant users access to my app, but access to their own Azure account. Is InteractiveBrowserCredential what I should be using?

Next, I looked into all of the different authentication flows. None of them seem quite right for my use case though. The closest one I found was the client credentials flow (https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow) since I am authenticating the user to their own Azure account and not my app. However, even this one doesn't seem quite right because when I looked up how to implement that flow with Azure Identity (https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/using-azure-identity.md#clientsecretcredential-and-clientcertificatecredential) I found out that I have to pass in the tenant Id. But the app won't know the user's tenant Id of the user before they log in. Which flow is right for this use case?

It seems like there is a gap in my understanding. How can I use the Azure SDK to implement an authentication flow that authenticates the user to their own Azure tenant (not authenticates them to my app) through the browser?

Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,606 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Shweta Mathur 27,786 Reputation points Microsoft Employee
    2022-02-07T10:35:36.003+00:00

    Hi @alma eyre ,

    Thanks for reaching out.

    As per my understanding, you are trying to authenticate users registered in Azure AD for your application.

    To access your application by Azure AD users, your application should also need to register in Azure AD.

    To register the application in Azure Active Directory,
    Sign into the Azure portal and select Azure Active Directory in the tenant where you want to register the application.
    Under Manage, select App registrations > New registration.

    171770-pic1.png

    The user or administrator must grant it the correct permissions via a consent process to access the application.

    171830-pic2.png

    Update the below applicationID, tenantID and redirect URI information in your application as registered in Azure Active Directory.

    171858-pic3.png

    Once your application is register, you can acquire the access token based on different OAuth flows which is needed to call various resources(Users in your case) or protected API based on your scenario.

    Azure Identity TokenCredential provide various flows to obtain an access token based on different scenarios.

    InteractiveBrowserCredential is one way to launches the system default browser to interactively authenticate a user and obtain an access token.
    Using access token, you can retrieve user’s info or access any other resource in Azure tenant. The InteractiveBrowserCredential uses Authorization Code Flow to authenticate users for browser based applications and to access resources further.

    Client credential flow is OAuth flow commonly used for server-to-server interactions that usually run in the background, without immediate interaction with a user and help to acquire the token and call protected web APIs.

    Sample Reference to use interactive credential flow in node : azure-sdk-for-js/interactive-browser-credential.md at main · Azure/azure-sdk-for-js (github.com)

    Hope this will helps. If you have any other questions on this. Please let us know.

    Thanks,
    Shweta

    --------------------------------------

    Please remember to "Accept Answer" if answer helped you.

    0 comments No comments

  2. alma eyre 11 Reputation points
    2022-02-08T16:14:03.353+00:00

    Is there any guide for which API permissions I should be granting for which Azure SDK methods? (Keeping in mind that I am trying to authenticate users to read access on resources in their own Azure account, not authenticate them to my app.)

    When I enabled the permissions as per the image you provided I get "ERROR. Scopes: https://management.azure.com/.default. Error message: invalid_client. AADSTS650057: Invalid resource. The client has requested access to a resource which is not listed in the requested permissions in the client's application registration. Client app ID: 480eb9fb-36f6-4381-92f6-af4b9e3bf1d7(Opal). Resource value from request: https://management.azure.com. Resource app ID: 797f4846-ba00-4fd7-ba43-dac1f8f63013. List of valid resources from app registration: 00000003-0000-0000-c000-000000000000.
    Trace ID: 1930e55e-c4d8-402d-8924-cd0b2b922300
    Correlation ID: f798622c-a4d1-4fb2-ad4b-077c265c6c7e
    Timestamp: 2022-02-08 16:01:20Z."

    So perhaps those permissions were too few.

    Next, I tried following this guide (https://learn.microsoft.com/en-us/graph/permissions-reference) and set the permissions I thought the Azure SDK methods I am using would need. But perhaps I was too liberal because I got this error instead: "ERROR. Scopes: https://management.azure.com/.default. Error message: invalid_client. AADSTS650054: The application '' asked for permissions to access a resource that has been removed or is no longer available. Contact the app vendor.
    Trace ID: 9c1c7cdf-bf7f-4408-9f4e-d1364b360000
    Correlation ID: 836ab643-ca40-4520-961c-e69337b2f836
    Timestamp: 2022-02-07 17:31:40Z."

    Also, these errors only show up when I use an organizational account. I have registered my app with the urls localhost:8083 and localhost:8085 and set "signInAudience": "AzureADandPersonalMicrosoftAccount", in the manifest. Despite this, I am still getting the error: "You can't sign in here with a personal account. Use your work or school account instead." when using a personal account. Is this related to API permissions? If not, what could be causing this error?

    Here are the SDK classes and methods the app is using:
    DefaultAzureCredential and InteractiveBrowserCredential from Azure Identity
    SubscriptionClient from arm-resources-subscriptions, and the subscriptions.list() method from that class.
    ResourceManagementClient from arm-resources, and the resourceGroups.list() and listByResourceGroup() method from that class.
    MetricsQueryClient from Azure Monitor SDK and the queryResource() method from that class.

    What should I refer to, to find the API permissions I need for these classes and methods?