-
Notifications
You must be signed in to change notification settings - Fork 0
Samples UsingMicrosoftGraph
This sample shows you how you use Blazorade ID to get an access token that you use when accessing Microsoft Graph. A similar sample is also available on the Blazorade ID repository on Github.
Microsoft.Graph uses TokenCredential objects as one way of authorizing requests to Microsoft Graph. We can create our own implementation that uses an access token received from ITokenService.
using Azure.Core;
public class StaticTokenCredential : TokenCredential
{
public StaticTokenCredential(string token, DateTimeOffset expiresOn)
{
this.AccessToken = new AccessToken(token, expiresOn);
}
private readonly AccessToken AccessToken;
public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
{
return ValueTask.FromResult(this.AccessToken);
}
public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
{
return this.AccessToken;
}
}Add the following @using statements to your Blazor component.
@using Microsoft.Graph
@using Microsoft.Graph.Models
@using Azure.Core
@using Blazorade.Id
@using Mdl = Blazorade.Id.Model
@using Blazorade.Id.Services
Then inject the following service into your component.
@inject ITokenService TokenService
Next, add the following code block to your component.
@code {
User? user;
protected async override Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if(firstRender)
{
await this.LoadUserAsync(Mdl.Prompt.None);
}
}
private async Task<GraphServiceClient?> GetGraphServiceClientAsync(Mdl.Prompt? prompt = null)
{
var tokenCredential = await this.GetTokenCredentialAsync(prompt);
if(null != tokenCredential)
{
var graphClient = new GraphServiceClient(tokenCredential);
return graphClient;
}
return null;
}
private async Task<TokenCredential?> GetTokenCredentialAsync(Mdl.Prompt? prompt = null)
{
var tokens = await this.TokenService.GetAccessTokensAsync(new GetTokenOptions { Prompt = prompt, Scopes = ["User.Read"] });
if(tokens.Count > 0)
{
var token = tokens.First().Value;
var expires = token.GetExpirationTimeUtc() ?? DateTime.UtcNow.AddHours(1);
return new StaticTokenCredential(token.RawData, expires);
}
return null;
}
private async Task LoadUserAsync(Mdl.Prompt? prompt = null)
{
var client = await this.GetGraphServiceClientAsync(prompt);
if(null != client)
{
this.user = await client.Me.GetAsync();
this.StateHasChanged();
}
}
}This variable holds a reference to the user object received from Microsoft Graph.
This method uses the injected ITokenService implementation to get an access token with the User.Read scope. It then uses that token to create an instance of the StaticTokenCredential class that you implemented.
If an access token is not found, the method returns null.
This method calls the GetTokenCredentialAsync method to get a token credential. If a token credential is available, the method creates a new instance of the GraphServiceClient class and returns it. If a token credential is not found, the method returns null.
This method is responsible for getting a GraphServiceClient instance using the method GetGraphServiceClientAsync. The method also defines an optional Prompt parameter which is sent down the method chain when getting a GraphServiceClient instance.
This allows us to attempt to load the user data without user interaction on the page. This is important, because most browsers block popup windows that are not created as a direct result of a user action, like clicking a button.
That would also be quite distractive to users, if all of a sudden, a popup window would appear on top of the page.
This method is called when the component has been rendered. Here, we attempt to automatically load the user data by calling the LoadUserAsync and setting the prompt parameter to Prompt.None so that the ITokenService implementation we are using does not require any user interaction when getting the requested access token.
The final step is to add UI code to your component that displays the User object loaded from Microsoft Graph.
<button @onclick="async () => await this.LoadUserAsync()">Get User Info</button>
@if(null != this.user)
{
<h2>User Information</h2>
<ul>
<li><strong>Display Name:</strong> @this.user.DisplayName</li>
<li><strong>Mail:</strong> @this.user.Mail</li>
<li><strong>Id:</strong> @this.user.Id</li>
</ul>
}If the user variable has been set, then we display the information in a simple unordered list. The button allows the user to explicitly start the process of getting an access token that is used to create a GraphServiceClient instance, which is then used to get the user information with.