3

I want to get access token to use it to fetch email from outlook using microsoft graph api. My application will be Console based c# application which will run automatically after every 20 min and will fetch the email.

I am new to c# as well as microsoft graph, this is my first task related to these technology.

Problem is:

When i tried to fetch token using client_Credentials i was successfully able to do so, but now that token is expired i want to get new token and if I try to generate new token it is returning the expired one only.

Relevant code:

result = await context.AcquireTokenAsync(resourceUri, clientCredential);

Using AcquireTokenSilentAsync method return as error: "Failed to acquire token silently as no token was found in the cache. Call method AcquireToken."

Relevant code:

result = await authContext.AcquireTokenSilentAsync(resourceUri, clientId);

My questions:

  1. Is accessing token using client credential is correct way to fulfill my need?

  2. I have read that using client_Credentials we do not need refresh_token, every time we try to connect we will get new token.

  3. How to get new token every time I want to connect?

  4. Any extra suggestion about how to approach to my main objective which are not asked in question would be dearly welcomed.

I'm attaching my code sample:

static async Task getAccessToken()
{
    authContext = new AuthenticationContext("https://login.microsoftonline.com/<tenantId>");
    try
    {
        result = await authContext.AcquireTokenSilentAsync(resourceUri, clientId);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
        try
        {

            result = await authContext.AcquireTokenAsync(resourceUri, clientCredential);

            Console.WriteLine("" + result.AccessToken+"\n\n");
        }
        catch (Exception e)
        {
            Console.WriteLine("\n AcquireTokenAsync failed\n");
            Console.WriteLine(""+e);
        }
    }
    if (result == null)
    {
        Console.WriteLine("Canceling attempt to get access token.\n");
        return;
    }
    Console.WriteLine(result.AccessToken);

}

1 Answers1

2

You're mixing a two different OAuth flows (Authorization Code and Client Credentials). You should only need to call AcquireTokenAsync with the correct credentials. Whenever you need a new token (each token lives about an hour), you re-execute this method to get a new token:

static async Task<AuthenticationResult> getAccessToken()
{
    ClientCredential clientCredential = new ClientCredential("YOUR_APP_ID", "YOUR_APP_SECRET");
    AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/YOUR_TENANT_ID");
    AuthenticationResult result = null;

    try
    {
        result = await authContext.AcquireTokenAsync("https://graph.microsoft.com", clientCredential);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }

    if (result == null)
        Console.WriteLine("Canceling attempt to get access token.");
    else
        Console.WriteLine(result.AccessToken);

    return result;
}
Marc LaFleur
  • 31,987
  • 4
  • 37
  • 63
  • Thanks @Marc, I have to access outlook mail with my application and I think "/v1.0/users/123e4567-e89b-12d3-a456-426655440000/mailFolders('Inbox')/messages" is the API I have to call. Is it correct? and how to get UserID ? – Rishabh Verma Mar 05 '19 at 07:09
  • Actually all the credentials is provided to me by some other team and I don't have access to Azure portal. So should I ask them to create a new User and share the credential or I can do that using code. Apologies if question sound really naive!! – Rishabh Verma Mar 05 '19 at 07:32
  • With client_credentials there _is_ no User. You're authenticating your "App" itself, not a "User using your App" – Marc LaFleur Mar 05 '19 at 16:04
  • So how should I move forward from here and which API to use? Previously I was referring this answer of your [https://stackoverflow.com/a/53125977/11134640] – Rishabh Verma Mar 06 '19 at 05:41
  • I'm not sure how to answer that. It depends on your app and what you're looking to do. Normally you map out your scenario and determine which APIs you need. How you authenticate depends on which APIs you're using. – Marc LaFleur Mar 06 '19 at 14:58
  • Thanks @Marc for your time. Actually I have to perform three tasks. 1) fetch a mail 2) read the attachments (if any) 3) transfer the mail to different folder. It is going to be c# console application and will run automatically after some specified amount of time. I have been given few information like clientID, Client_Secret_Key, TenantID and redirectUri. Now if you can suggest how to approach? – Rishabh Verma Mar 07 '19 at 05:58
  • [https://learn.microsoft.com/en-us/graph/auth-v2-service#5-use-the-access-token-to-call-microsoft-graph] the user that this post is talking about how to get their detail? Will the team having access to AAD have to create these user? – Rishabh Verma Mar 07 '19 at 07:12
  • When using Client Credentials, there _is no user_. All you need is consent from an Admin for the tenant. – Marc LaFleur Mar 07 '19 at 18:43
  • Okay. Then which API should I call to fetch email. If possible , can you please write a code or give a overview in 2-3 line how to fetch emails. – Rishabh Verma Mar 08 '19 at 02:07