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).
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:
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:
- You logged into a tenant, and
- 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.
-
Microsoft.Identity.Client:
dotnet add package Microsoft.Identity.Client
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:
-
Microsoft.Graph:
dotnet add package Microsoft.Graph
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:
If your email address doesn't belong to the tenant you want to query, you'll see the result screen like this:
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:
- Using Blazor WASM app hosted on ASWA,
- Using MSAL for authentication and authorisation against AAD, and
- Using Microsoft Graph to access to 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.
Top comments (2)
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).
@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.