Search code examples
azuremicrosoft-graph-apimsal

MSGraph best auth flow for single sign on


I am trying to understand the Microsoft Graph authentication flows and what I should use for my application. It already works, but there are some issues with the current setup, and we are rebuilding it for AWS and I want to have a closer look at how to properly handle the MS Graph auth flow.

Use case: I am currently building a node.js express API and I would like to add an integration with Microsoft Graph. So that when a user goes on our portal, they go to calendars and go to the M365 and press add integration. The user then needs to authenticate once and from then on the calendar can be retrieved. In order to be used by the devices that are connected to our portal (these devices run our Android app on small tablets). So the way I would like to retrieve the data is by using webhooks, so we can listen whether a booking is created/modified/deleted and update the data in our database. Also, we would like this to work for multi-tenant environments.

How I did it so far: In my current app, I used the following libraries specific for MS Graph:

"@microsoft/microsoft-graph-client": "^2.0.0",
"msal": "^1.0.0",
"passport-azure-ad": "^4.2.0",
"simple-oauth2": "^3.1.0",

I started by configuring passport with the OIDCStrategy with several env parameters like clientId, identityMetadata, etc together with the signInComplete function. So the moment the user want to authorize the /auth/signin gets called and uses the passport.authenticate('azuread-openidconnect') together with some parameters to get the login prompt. This would then request permission to add the Cleverspace azure app to the tenant. If this is accepted then it would call the /auth/callback method and if everything went successful the signincomplete function is called. This then creates the oath2 token by using the simple-oauth2 library with the client and auth env parameters. The function just saves the MS Graph user to our database together with its token. If the token gets expired, we renew it by using the simple-oauth2 library again and use the .refresh method on the token.

The problem: Now I wonder if this is still a valid way of authentication, and also if there is a way to handle problems with the signin flow. Because as of now when the user does the signin process but the grant admin consent flow is disabled they get the message that admin approval is needed. For some reason when the user would log in with the admin account to add the application to the environment and remove the admin account from the portal to add a non admin account that would retrieve the calendar, yet it seems it doesn't work. As that account is unable to retrieve any data, I am assuming here that this is because the account used to add the azure application is the account that is needed to get the data from their environment. Unless I'm doing something wrong or missing something, as of now I have no idea how to properly solve this.

The question:

  1. Is my current auth flow valid for my use case or do I need to use a different flow that has Single sign in, because having to log in multiple times to keep the system alive is quite annoying?
  2. When I keep the current flow, is there a way to solve the Admin approval issue I'm facing?
  3. If a different flow is needed, is the "Need Admin approval" flow still a possible result due to their azure config, and is there a solution to fix my issue in that case?

Any ideas?

Thanks in advance!


Solution

  • Create an Azure AD Application by selecting "
    Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) " to support Multitenant environments:

    enter image description here

    The authentication flow you are implementing is valid. If you do not want users to log in multiple times, then you can implement On-Behalf-Of flow. Refer this SO Thread by me.

    When I tried to login to the application, I got the same error as below:

    enter image description here

    The error "Need admin approval" usually occurs if the API permissions added to the Azure AD Application has not been granted admin consent.

    You must have either Global Administrator, Privileged Role Administrator, or Application Administrator role to grant Admin consent.

    Go to the Azure Portal -> Microsoft Entra ID -> App registrations -> Your App -> API permissions -> Grant Admin Consent

    enter image description here

    Otherwise, Grant tenant wide admin consent by using below endpoint:

    https://login.microsoftonline.com/organizations/adminconsent?client_id=ClientID
    

    And click on accept:

    enter image description here

    The Admin consent granted to the API permissions:

    enter image description here

    If still the issue persists, check the below:

    Go to Azure Portal -> Enterprise Applications -> Consent and Permissions -> User consent settings

    Set the User consent settings to Allow user consent for apps:

    enter image description here

    Use the Admin Consent Workflow if you don't want to grant permission for all users to access the app:

    Go to Enterprise Applications -> Consent and permissions -> Admin consent settings

    enter image description here

    When the user logins, the Approval Required screen:

    enter image description here

    Reference:

    Configure the admin consent workflow - Microsoft Entra