Microsoft Azure AD oAuth flow with Strapi enterprise project

Dear Strapi Devs,

Recently I got hired to build out a new project that requires microsoft login to enable users from Azure AD / Microsoft 365 to be able to login in to a website that has the backbone of Strapi CMS.

I followed a few tutorials to integrate the oAuth flow “microsoft” explained in this tutorial and while this works fine, I need a more complete solution.

The Strapi microsoft provider only creates a user in the Strapi backend but completely ignores the returned data such as access_tokens and refresh_tokens that are mandatory to be used to parse the microsoft api’s. While this is fine if you are planning to continue with the user jwt that is generated / provided by Strapi, this but isn’t the case in my project.

Requirements System

  • A user should be able to login to Strapi backend with his microsoft account from a front-end website
  • The logged in user in the front-end should be able to get information from the microsoft graph api to get metadata of the user such as profile photo, tenant_id / group_ids, phone numbers and so forth.
  • The logged in user in the front-end should be able to query Strapi collection types as usual
  • The access_token returned by Strapi does not contain a refresh token out of the box because it uses the oauth grant flow on machine level which does not return the refresh token according to the docs.
  • Storing the access_token in localstorage is due to security risks not an option.
  • The access_token should periodically be refresh because access tokens are invalidated every 60 minutes by Azure AD.

Research done
After a little search on the web I found a library officially supported by Microsoft called MSAL
MSAL provides the tools to be able to login to microsoft AD in a react app with wrapper functions that redirect to microsoft online to login and save access_tokens etc in a secure session storage.

Unfortunately when logging on the front react app we don’t have a token to validate requests to Strapi, because we simply didn’t login to Strapi /api/connect/microsoft if we would use the MSAL library. So this is also not an option I guess.

Desired solution
We would like to be able to login to Strapi via a button in the front-end and upon a success login a strapi user should be created that can execute requests on behalve of the JWT token given by Strapi, but also has the opportunity to execute requests to the external microsoft Graph API to gather meta data such as profile photo etc which are not stored in Strapi by default.

Storing the access_token in the database might be a solution but also security wise this may not be the best solution.

Lastly, the whole thing should be super secure and should automatically refresh the access token every 60 minutes. (Since the token life span of the token provided by Azure AD is 3500 seconds)

Architecture

Help, tips and feedback is highly appreciated. Thanks in advance!

Cheers,
Kiwi Coder

System Information
  • Strapi Version: 4.2.3
  • Operating System: macOS Monterey
  • Database: Mysql
  • Node Version: 14.19.1
  • NPM Version: 6.14.16
  • Yarn Version: 1.22.17

Hey Kevin,

I’m in the same situation and curious what solution you settled on…mind sharing?

1 Like

Hey dbeaudway,

I am sorry i haven’t got back to you anytime sooner.
I did not receive any reminder in my mail.

Did you make any progress so far?

Best Regards,

I’m currently trying to hack Strapi to handle access_token directly instead of its own created jwt.
Then only the authorized client have to store the access_token, we would just verify it, verify claims and forward it to other services.

I’m not using the access_token from Microsoft for that, I’m using another auth server, so it may be slightly different than what you need.

Hi @NateR42
Is this related to the modification you made to the bootstrap method to allow Microsoft single tenant?
I am trying to understand if this change was to allow frontend users to authenticate with Microsoft Azure AD and then continue to use the frontend application, or if it was to authenticate admin users who log into the Strapi backend/portal?

Nope this is not related. It’s for another Strapi configuration.

But these modifications are both for end user authentication (handled with user-permissions plugin), not for Strapi backend.

The one for Microsoft tenant is because purest handles only the “common” endpoint, so I had to adapt to handle a business endpoint.

And my last adaptation done this week is to add the keycloak provider too which is not present in this plugin, also I wanted to use the access_token from oauth2 instead of the Strapi generated one.

1 Like

@NateR42 This is undocumented but you can make your own auth provider in strapi. still this would mean you would have to recreate a ui to set content-type permissions