DEV Community

Cover image for MS Graph, Blazor WebAssembly and Azure Static Web Apps
Justin Yoo for Microsoft Azure

Posted on • Originally published at devkimchi.com

MS Graph, Blazor WebAssembly and Azure Static Web Apps

Azure Static Web Apps (ASWA) offers a straightforward authentication feature. With this feature, you don't need to write a complicating authentication logic by your hand and can sign in to ASWA. By the way, the authentication details from there only show whether you've logged in or not. If you need more information, you should do something more on your end. Throughout this post, I'm going to discuss how to access your user profile data stored in Azure Active Directory (AAD) through Microsoft Graph from the Blazor WebAssembly (WASM) app running on an ASWA instance.

You can find the sample code used in this post on this GitHub repository (docs in Korean).

GitHub logo fusiondevkr / fusiondevkr

fusiondevkr 백엔드 세팅

Office for Fusion Dev Korea

Fusion Dev Korea 에서 운영하는 애플리케이션을 관리합니다.

구조

  • resources: 애저 리소스를 구성하는 ARM 템플릿 및 Biceps 템플릿 파일
  • src: 프론트엔드 및 백엔드 애플리케이션
  • power/flow: 파워 오토메이트 솔루션
  • power/apps: 파워 앱스 솔루션

Retrieving Authentication Data from Azure Static Web Apps

After publishing your Blazor WASM app to ASWA, the page before log-in might look like this:

Before log-in

If you want to use AAD as your primary identity provider, add the link to the Login HTML element.

After the sign-in, you can retrieve your authentication details by calling the API endpoint like below. For brevity, I omitted unnecessary codes.

Here are the authentication details from the response:

As mentioned above, there's only limited information available from the response. Therefore, if you need more user details, you should do some additional work on your end.

Accessing User Data through Microsoft Graph

You only know your email address used for log-in. Here are the facts about your logged-in details:

  • You signed in through your tenant where your email belongs.
  • The sign-in information TELLS your email address used for log-in.
  • The sign-in information DOESN'T TELL the tenant information where you logged in.
  • The sign-in information DOESN'T TELL the tenant information where the ASWA is hosted.
  • The sign-in information DOESN'T TELL the tenant information where you want to access.

In other words, there are chances that all three tenants details – the tenant where you logged in, the tenant hosting the ASWA instance, and the tenant where you want to access – might be different from each other. All you know of my details are:

  1. You logged into a tenant, and
  2. You only know my email address used for log-in.

Then, how can you know your user details from the tenant that you want to access?

First of all, you need to get permission to get the details to the tenant. Although you signed in to ASWA, it doesn't mean you have enough permission to access the resources. Because ASWA offers Azure Functions as its facade API, let's use this feature.

When calling the facade API from the Blazor WASM app side, it always includes the auth details through the request header of x-ms-client-principal. The information is the Base64 encoded string, which looks like this:

Therefore, decode the string and deserialise it to get the email address for log-in. Here's a POCO class for deserialisation.

With this POCO class, deserialise the header value and get the email address you're going to utilise.

All the plumbing to get the user details is done. Let's move on.

Registering App on Azure Active Directory

The next step is to register an app on AAD through Azure Portal. I'm not going to go further for this step but will give you this document to get it done. Once you complete app registration, you should give it appropriate roles and permissions, which is the application permission instead of the delegate permission. For example, User.Read.All permission should be enough for this exercise.

Once you complete this step, you'll have TenantID, ClientID and ClientSecret information.

Microsoft Authentication Library (MSAL) for .NET

You first need to get an access token to retrieve your details stored on AAD. There are many ways to get the token, but let's use the client credential approach for this time. First, as we're using Blazor WASM, we need a NuGet package to install.

After installing the package, add several environment variables to local.settings.json. Here are the details for authentication.

To get the access token, write the code below. Without having to worry about the user interaction, simply use both ClientID and ClientSecret values, and you'll get the access token. For example, if you use the ConfidentialClientApplicationBuilder class, you'll easily get the one (line #16-20).

Once you have the access token in hand, you can use Microsoft Graph API.

Microsoft Graph API for .NET

To use Microsoft Graph API, install another NuGet package:

And here's the code to get the Graph API. Call the method written above, GetAccessTokenAsync() (line #4-8).

Finally, call the GetGraphClientAsync() method to create the Graph API client (line #1) and get the user details using the email address taken from the ClientPrincipal instance (line #4). If no user data is queried, you can safely assume that the email address used for the ASWA log-in is not registered as either a Guest User or an External User. Therefore, the code will return the 404 Not Found response (line #7).

The amount of your information would be huge if you could filter out your details from AAD.

You don't want to expose all the details to the public. Therefore, you can create another POCO class only for the necessary information.

And return the POCO instance to the Blazor WASM app side.

Now, you've got the API to get the user details. Let's keep moving.

Exposing User Details on Azure Static Web Apps

Here's the code that the Blazor WASM app calls the API to get the user details. I use the try { ... } catch { ... } block here because I want to silently proceed with the response regardless it indicates success or failure. Of course, You should handle it more carefully, but I leave it for now.

In your Blazor component, the method GetLoggedInUserDetailsAsync() is called like below (line #6, 18).

If your email address belongs to the tenant you want to query, you'll see the result screen like this:

After the log-in - user found

If your email address doesn't belong to the tenant you want to query, you'll see the result screen like this:

After the log-in - user not found

Now, we can access your user details from the Blazor WASM app running on ASWA through Microsoft Graph API.


So far, I've walked through the entire process to get the user details:

As you know, Microsoft Graph can access all Microsoft 365 resources like SharePoint Online, Teams and so forth. So if you follow this approach, your chances to use Microsoft 365 resources will get more broadened.

Discussion (2)

Collapse
ryanspain profile image
Ryan Spain • Edited

Great post, thanks!

Could you explain why application permissions was choosen over delegated permission?

As I understand it, application permission is giving the logged in user access to all users data in the directory as opposed to just their own (through delegated permission).

Collapse
justinyoo profile image
Justin Yoo Author

@ryanspain Thanks for your comment! It really depends on how you use the app. If you want to use the delegated permission, it's totally OK.