How can I create GraphServiceClient using AccessToken from AuthenticationResult

Ken Smith 130 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
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
12,581 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Sourabh Gupta 800 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".


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.