How can I create GraphServiceClient using AccessToken from AuthenticationResult

Ken Smith 105 Reputation points
2024-05-07T16:19:11.86+00:00

In my code I already used AcquireTokenSilent and AcquireTokenInteractive; they provided an AuthenticationResult (with AccessToken) which I would like to use to create a GraphServiceClient. I could not find a suitable constructor so I hacked a solution shown below. Is there a better way? Why is there no constructor for GraphServiceClient which takes an AuthenticationResult.AccessToken?

// TRICKY! Create a GraphServiceClient using an AccessToken that was previously acquired via AcquireTokenInteractive. 
_userAuthStatus.GraphServiceClient = new GraphServiceClient(new CustomTokenCredential(_userAuthStatus.AuthResult.AccessToken), scopes);

// @ken 4/11/2024 Ken wanted to create a GraphServiceClient using an AccessToken that was previously acquired!
// @ken Why doesn't GraphServiceClient have a constructor to do this?  Or is this technique a bad idea?
internal class CustomTokenCredential : TokenCredential
{
	private AccessToken _token;
	// TODO Find out why AccessToken constrcutor has parameter for expiresOn which is totally ignored here!
	//		Also, the original token already has a claim "exp" which specifies expiration!
	public CustomTokenCredential(string token) : this(new AccessToken(token, DateTimeOffset.MinValue)) { }
	//public CustomTokenCredential(string token) : this(new AccessToken(token, new DateTimeOffset(DateTime.Now.AddSeconds(10)))) { }

	public CustomTokenCredential(AccessToken accessToken)
	{
		_token = accessToken;
	}
	public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
	{
		return _token;
	}
	public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
	{
		return new ValueTask<AccessToken>(_token);
	}
}

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
10,813 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,817 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Sourabh Gupta 795 Reputation points Microsoft Vendor
    2024-05-12T13:50:42.17+00:00

    Hi Ken Smith,

    Thanks for reaching out.

    There exists a constructor which takes an object of a type derived from IAuthenticationProvider, even the class used in your code ("Custom Token Credential") above is also derived from IAuthenticationProvider Interface.

    The way you are creating a GraphServiceClient is also a good way from already acquired token.

    Another elegant way to do the same with some less lines of code is as below.

    
    public GraphServiceClient GetAppGraphClient(string accessToken)
    {
        var authProvider = new DelegateAuthenticationProvider(async (requestMessage) =>
        {
            // Set the Authorization header with the access token
            requestMessage.Headers.Authorization = new    System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
        });
    
        var appGraphClient = new GraphServiceClient(authProvider);
    
        return appGraphClient;
    }
    

    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".