Patrick Lamber
Patrick Lamber IT Geek focusing on Microsoft collaboration software.

How do I authenticate against Azure AD using React, MSAL.JS and ASP.NET Core 3.0?

Microsoft is evolving the Azure Active Directory (v1.0) endpoints into the new Microsoft identity platform (v2.0). You should give it a try and consider a move to this new platform. This article if you are interested to understand more and identify the main reasons for performing the switch.

From a software development perspective, you used ADAL (Azure Active Directory Library) to help you get authenticated against the old Azure Active Directory (v1.0) services. If you want to integrate your application with the Microsoft identity platform (v2.0), you can use MSAL (Microsoft Authentication Library) instead. An overview of MSAL is given here.

The scenario

I wanted to implement both, an ASP.NET Core project to act as an API backend, and a standard CRA React project to act as a UI, but with the convenience of hosting both in a single app project that can be built and published as a single unit. The authentication has to be handled on the client-side forcing the user to authenticate once accessing any page. Once authenticated, I wanted to provide simple user information about the logged-in user using Microsoft Graph.

You can find the results of this project in this GitHub. I used the existing React project template with ASP.NET Core as a foundation for my project.

What is the website doing?

The users are immediately forced to authenticate themselves once accessing the website. MSAL.JS is used to handle the whole authentication flow. For this, an Azure AD application was registered on the target tenant.

Once authenticated, the user sees basic information about him/her on the upper-right corner. This information is coming from the authentication token provided by Azure AD. If you just want to authenticate the user using Azure AD, we are already done.

I also added a section that shows how to get the basic information about the user using Microsoft Graph. This is handled by the page Get Graph data and the Microsoft Graph JavaScript libraries included in the project.

At this stage, there is no further interaction with ASP.NET Core. I am not consuming any secured API on our back-end. This will be handled in a future post.

How do I get started?

If you just want to test it without additional hassle, just run the project. I already configured a multi-tenant application in my test tenant that allows you to authenticate against Azure AD.

Follow the steps below if you want to have your dedicated Azure AD application.

I want to use my dedicated Azure AD application

If you want to use your dedicated Azure AD application, follow these basic steps. You need to ensure that you are properly configuring a new application in Azure AD. Once configured, you need to change the configuration of the application in the code.

Register your app

  • Go to the App Registration in Azure AD
  • Press New registration
  • Specify a name and choose the desired account types (Single tenant, Multitenant) and then press Register
  • Copy the Application (client) ID (yourClientID) and Directory (tenant) ID (yourTenantID)
  • Go to Authentication
    • Under Redirect URIs create two entries: https://localhost:44321/signin-oidc, https://localhost:44366/
    • Under Implicit grant select Access tokens and ID tokens

Change the configuration in Visual Studio to use your created application

  • Go under ClientApp -> src -> msal -> MsalConfig.js
    • Replace the clientId value with yourClientID
    • In case you configured a single tenant application, replace common in the authority value with youTenantID

Key aspects in the code

The app is using the React project template with ASP.NET Core as a basis. I just removed the unnecessary Weather controllers and added some minor things.

Install the required client-side libraries

I used NPM to install the necessary client-side libraries. msal is used to get MSAL.JS while @microsoft/microsoft-graph-client is used for the Microsoft Graph integration part.

In package.json you should find these entries.

1
2
"@microsoft/microsoft-graph-client": "^2.0.0",
"msal": "^1.2.0",

Forcing the authentication in React

One of my requirements was to force the authentication whenever a user is accessing a page. To implement this, I found it convenient to use the React Higher-Order Component pattern to encapsulate the MSAL.JS authentication logic. The MsalAuthProvider.js is responsible for this part. The authentication is handled by the logic below. If a user is not authenticated, authenticate him/her using the Azure AD settings in our config.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
async componentWillMount() {
    msalAuth.handleRedirectCallback(() => {
        let userAccount = msalAuth.getAccount();

        this.setState({
            isAuthenticated: true,
            user: userAccount
        });
    }, (authErr, accountState) => {  // on fail
        console.log(authErr);

        this.setState({
            hasError: true,
            errorMessage: authErr.errorMessage
        });
    });

    if (msalAuth.isCallback(window.location.hash)) {
        this.setState({
            auth: {
                renewIframe: true
            }
        });
        return;
    }

    let userAccount = msalAuth.getAccount();
    if (!userAccount) {
        msalAuth.loginRedirect({});
        return;
    } else {
        this.setState({
            isAuthenticated: true,
            user: userAccount
        });
    }
}

This function is used in the App.js file to wire-up the authentication and associate it with the main React app using the High-Order Component pattern.

1
2
3
4
5
6
7
8
9
10
11
class RootApp extends Component {
    render() {
        return (
            <Layout {...this.props} >
                <Route exact path='/' component={Home} />
                <Route exact path='/graph-data' component={GraphData} />
            </Layout>
        );
    }
}
export const App = withAuth(RootApp);

The GraphData.js file is handling the creation of the Graph client and the retrieval of the graph information of the user. You can find under GraphService.js the part of the code which is requesting a new token for the Graph request.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const accessTokenRequest = {
    scopes: ["user.read"]
}
var accessToken = null;
try {
    accessToken = await msalAuth.acquireTokenSilent(accessTokenRequest);
}
catch (error) {
    console.log("AquireTokenSilent failure");
    accessToken = await msalAuth.acquireTokenPopup(accessTokenRequest);
}

if (accessToken) {
    var user = await getUserDetails(accessToken);

Go and change the MsalConfig.js if you want to manipulate the authentication settings for MSAL.JS. You can find the configuration options of MSAL.JS under this link.

Summarizing

With this GitHub project I am showing you how to authenticate against Azure AD using React and ASP.NET core. I will improve the current code and provide more samples on that repository.

Happy coding.

comments powered by Disqus