Identity: Microsoft Authentication with React and Asp.NET Identity

Mahdi Karimipour
8 min readAug 19, 2021

End to end guide on how to implement external authentication with Microsoft for React apps. It also includes using Asp.NET 5.0 API as the backend, hosted on Azure app service and behind Azure API Manager, along with Asp.NET Identity as it’s Identity backend.

The Need

There are a few ways you could integrate Microsoft Authentication with a Single Page Application like React, while relying on your Asp.NET 5.0 API and Asp.NET Identity system.

In this post, I have tried to implement it without using front end components, and rely on my Asp.NET API to orchestrate the entire process, in a way that is repeatable for other Social Logins as well.

I have also used Azure App Services for hosting along with a custom domain, and Azure API Manager to serve the traffic. This in turn added some complexity to the mix, which I will cover in this post as well.

By the way, this topic belongs to the series to set up Authentication and Authorisation for Asp.NET and React ecosystems.

  1. Asp.Net Core Web Api Setup
  2. React Single Page App Setup
  3. Asp.NET Identity DB Setup
  4. Email Sender
  5. Sign Up & Activation
  6. Check User Authentication Status
  7. Change Password
  8. Sign In
  9. Policy Based Access Management
  10. Token Refresh
  11. Google Authentication with React and Asp.NET API
  12. Microsoft Authentication with React and Asp.NET API
  13. Twitter Authentication with React and Asp.NET API

Assumptions

I assume you have your React, Asp.NET API with Asp.NET Identity already set up and in place, and if you haven’t, you can follow the above links to do so.

When I write how-tos, I generally follow the way traffic flows in my application, as it would be easier to understand and follow the whole thing. Based on that, I start with the front end, where user clicks on “Login With Microsoft”.

1. Frontend: Login with Microsoft

In terms of the end result, as expected, here is my simple auth screen. Please note I am NOT using any frontend Microsoft component such as react-microsoft-login, as I’d like to give the power to my Asp.NET Identity to manage it.

The code behind this UI is straightforward and is simple HTML and JS. If you’d like to read more on my normal authentication using JWT Bearer token, refer to Sign Up with Pellerex or Sign In with Pellerex. As you can see below, all I have is a simple form, and a submit button.

Notes to consider about the above form:

  • Api Gateway: My Asp.NET API is hosted using Azure App Service, and served via Azure API Manager. By looking at the URL, you see the below fragments:
  • Scheme + Base: https://api.domain.com
  • Identifying Fragment: /identity
  • Route Versioning: /v1
  • Controller Action: /account/external-login
  • Redirect Uri: This is the address where eventually will be called when user successfully authenticates with Microsoft, and get redirected to your API. However this is NOT the first url when user heads back to your API. There is another path which will be called right after a successful auth, and that is by default “microsoft-signin”. More on this later

There are some complications with such set up which I will cover later on. In the meantime if you’d like to read more on API Versioning, refer to Route Versioning for Asp.NET 5.0 APIs

Identifying Cookie

Right before our API redirects the user to Microsoft, it will create a cookie on your website called “.AspNetCore.Correlation”. When the user gets redirected back to your website, Asp.NET Identity checks for the same cookie to exist, and this is to prevent CSRF attacks. I will get back and talk about this cookie shortly.

2. Backend: External-Login

Next step in our flow is where the user presses the Microsoft button, and calls my Asp.NET API “external-login” route, in which I construct the redirect URL, and generate the properties for Microsoft Login, returned to my App in the form of a challenge.

3. Microsoft Consent Screen

Next if you haven’t configured Microsoft to receive the Auth requests, it’s now time toh head over to Microsoft Consent Screen Setup and configure it. If you want to publish your own logo to Microsoft, and if some other conditions need to be met, Microsoft needs to verify your app through a formal process.

4. Microsoft Credentials

After that go to the new App Registration, and click on “Certificates and Secrets”, and set up your ClientId and ClientSecret which we need to be able to talk to Microsoft APIs. As part of that process, you will also need to set up some Urls, one is the domain for your React app (domain.com), and the other is the redirect Url back to your Asp.NET API.

Secret ID vs Client ID

When setting up Microsoft Auth, there are two values that might be confusing as Client ID. There is one SecretID which you see in the above photo, and that is NOT your ClientId. To get your ClientId for this purpose, click on Overview tab (visible in the above image), and pick the value next to “Application (client) ID”.

Time Waster Alert

There are two Urls that we set up as Redirect URLs. One is the redirect that we set in Step 2 above, in our API, and the second is the one we set in Step 4 as part of Microsoft Credentials Setup process. To help you avoid wasting time, here is how the flow works:

Redirect to Microsoft: First your API will initiate the process by sending the user to Microsoft.

Microsoft Redirect Back: After a successful login, Microsoft will redirect the user back to your API, but to an already configured Url by your Asp.NET Identity middleware. That is called https://api.domain.com/identity/signin-microsoft. Don’t search through your code, as you haven’t set this, and this has been configured by default, I mean the signin-microsoft part. The rest of that Url has been configured by us, refer to Step 1 for that.

Middleware Redirects: And finally your middleware will redirect the user back to the callback Url we designated in Step 2: https://api.domain.com/identity/v1/account/external-auth-callback?returnUrl={returnUrl}

Return Url: The return URL you see at the end, that is just for your front end, to send the user back to the screen they were on, before they pressed SignIn button on your website.

Hence, as you can see, what you give Microsoft, is the middleware Url, and not the final callback Url in your controller.

Here is how I set those credentials in my application, and for the sake of completeness, I have included my entire Identity Config here:

Note

Configuration, plumbing and troubleshooting your software foundation take a considerable amount of time in your product development. Consider using Pellerex which is a complete foundation for your enterprise software products, providing source-included Identity and Payment functions across UI (React), API (.NET), Pipeline (Azure DevOps) and Infrastructure (Kubernetes).

Exception: Cookie not Found

If like me, you have put your API behind a load balancer or gateway like Azure API Manager, you are now going to hit another challenge. Once user authenticates successfully, on their way back to your API’s middleware (the signin-microsoft address), they could face the below 500 error (The page isn’t working. It is currently unable to handle this request).

If you look at the address bar, you would realise it is not set to your custom domain like https://api.domain.com, but it is set to your Azure Website domain: https://xyz.azurewebsites.net..

The reason behind the exception, and also the behaviour is that Azure Api Manager doesn’t forward some of the headers including the host header, so Microsoft would simply redirect to the Url behind the scene (i.e. Azure Websites). If you remember from Step 1, we said there is an identifying cookie set before redirect to Microsoft, and that cookie is set to https://api.domain.com. Now when the user gets redirected back to your API, and the host is set to https://xyz.azurewebsites.com, surely it won’t be able to find the cookie there, and that is the reason behind Cookie Not Found exception.

The fix for this, is to make the API to represent itself as https://api.domain.com, and you could do it by injecting the below code into your middleware:

5. Callback

Now it is time for our callback route to be called, which is after our middleware callback by Microsoft (signin-microsoft one).

Consider the below points for the above snippet:

  1. signInManager.GetExternalLoginInfoAsync: What this does is to grab all the arguments in the URL coming back from Microsoft, make some other calls back to Microsoft to verify the request, and then translate it to user info we are after.
  2. accountService.ExternalLogin: I will cover this in the next section.
  3. Trasnfer the User Tokens to SPA: The other part that needs some attention here, is how to transfer the generated token to be used by your React app. The thing is, this is a call not initiated by your React app, and we need to find a way to transfer the tokens to your React app.
  4. First of all, the approach I have taken regarding external logins, is to rely on them “Just” to authenticate my users. Once done, I will translate that into my own login procedures, and generate my own JWT access and refresh tokens, which will be managed by the Asp.NET APIs.
  5. Knowing that, I generate the JWT tokens, and transfer that to my client using Cookies, as you see in the above snippet. Finally I redirect my user to a page, responsible for reading that Cookie and extracting the JWT tokens to be used by my frontend app.
  6. This is a pretty clean, no hacky, way to manage the Auth flow between React App, and Asp.NET API using Asp.NET Identity as the Identity backend.

6. Manage User Identity

And the last part which is the easiest, is to extract user information, and create or associate the Microsoft login, with any already existing profile in our system.

In case you’d like to read more on what’s inside Microsoft Auth Manager, refer to Claims Based Auth System using Bearer Token.

Note

Configuration, plumbing and troubleshooting your software foundation take a considerable amount of time in your product development. Consider using Pellerex which is a complete foundation for your enterprise software products, providing source-included Identity and Payment functions across UI (React), API (.NET), Pipeline (Azure DevOps) and Infrastructure (Kubernetes).

Pellerex: Identity Foundation for Your Next Enterprise Software

How are you building your current software today? Build everything from scratch or use a foundation to save on development time, budget and resources? For an enterprise software MVP, which might take 8–12 months with a small team, you might indeed spend 6 months on your foundation. Things like Identity, Payment, Infrastructure, DevOps, etc. they all take time, while contributing not much to your actual product. These features are needed, but they are not your differentiators.

Pellerex does just that. It provides a foundation that save you a lot development time and effort at a fraction of the cost. It gives you source-included Identity, Payment, Infrastructure, and DevOps to build Web, Api and Mobile apps all-integrated and ready-to-go on day 1.

Check out Pellerex and talk to our team today to start building your next enterprise software fast.

--

--