1

I have a table in a database with emails and their refresh tokens of multiple Hotmail/Outlook.com accounts (nothing else).

I'm trying to create an Access Token using the Refresh Token but I can't find any code using Microsoft.Identity.Client or Microsoft.Graph libraries to perform that action.

Here is the partial code in a console application:

static void Main(string[] args)
{
    /* other code */
    string email, refreshToken; // obtained from database
    TokenCache tokenCache = new TokenCache(); // how do i "fill" this object?

    ConfidentialClientApplication cca = new ConfidentialClientApplication(
        "appId",
        "redirectUri",
        new ClientCredential("appSecret"),
        tokenCache,
        null);

    IAccount account = cca
        .GetAccountsAsync()
        .Result
        .FirstOrDefault();

    AuthenticationResult result = cca
        .AcquireTokenSilentAsync(new string[] { "scopes" }, account)
        .Result;

    GraphServiceClient client = new GraphServiceClient("https://outlook.office.com/api/v2.0/",
        new DelegateAuthenticationProvider((requestMessage) =>
        {
            requestMessage.Headers.Authorization =
                new AuthenticationHeaderValue("Bearer", result.AccessToken);
            return Task.FromResult(0);
        }));

    var msgs = client
        .Me
        .MailFolders
        .Inbox
        .Messages
        .Request()
        .Select(m => new { m.Subject, m.ReceivedDateTime, m.From })
        .Top(10)
        .GetAsync();

    /* more stuff to do */
}

I have been able to do this using PHP but now I need it to do it in .net

UPDATE: I will show the complete code using the answer of Marc LaFleur

ConfidentialClientApplication cca = new ConfidentialClientApplication(
    appId,
    redirectUri,
    new ClientCredential(appSecret),
    new TokenCache(),
    null);
AuthenticationResult result = (cca as IByRefreshToken).
    AcquireTokenByRefreshTokenAsync(scopes, refreshToken).Result;

GraphServiceClient client = new GraphServiceClient(
    "https://outlook.office.com/api/v2.0/",
    new DelegateAuthenticationProvider((requestMessage) => {
            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
            return Task.FromResult(0);
    }
));

var msgs = client.Me.MailFolders.Inbox.Messages.Request().
    OrderBy("receivedDateTime DESC").
    Select(m => new { m.Subject, m.ReceivedDateTime, m.From }).
    Top(10).
    GetAsync().Result;
2
  • What's wrong with the code you have, exactly? Commented Mar 29, 2019 at 2:15
  • @Zer0 I don't known how to serialize the refresh token in the tokenCache object (see comment in line 5) so i can get the access token with it (see cca.AcquireTokenSilentAsync in line 10) Commented Mar 29, 2019 at 4:54

1 Answer 1

1

I believe you're looking for AcquireTokenByRefreshTokenAsync using Microsoft.Identity.Client -Version 3.0.2-preview:

ConfidentialClientApplication cca = new ConfidentialClientApplication(
    appId,
    redirectUri,
    new ClientCredential(appSecret),
    new TokenCache(),
    null);

AuthenticationResult result = (cca as IByRefreshToken).
    AcquireTokenByRefreshTokenAsync(scopes, refreshToken)
   .Result;
Sign up to request clarification or add additional context in comments.

8 Comments

I added the line after cca declaration and got "MsalServiceException: AADSTS70002: The provided request must include a 'client_secret' input parameter." I checked the cca object if the ClientCredential is correct and got: Assertion=0 Audience=0 Certificate=0 ContainsX5C=false Secret="appSecret" ValidTo=0. Something else that I forgot to add in my code?
Interesting, updating my example with an alternative method. It looks like something changed in 3.x.
There is no AcquireTokenByRefreshToken and no ExecuteAsync with it. But I wrote these lines ConfiguredTaskAwaitable<AuthenticationResult> awaiter = ccaRt.AcquireTokenByRefreshTokenAsync(scopes, refreshToken).ConfigureAwait(false); AuthenticationResult result = awaiter.GetAwaiter().GetResult(); tried false and true but still got the same error in both cases.
Ah, that's it. Try using 3.0.2-preview instead of 2.7.1: Install-Package Microsoft.Identity.Client -Version 3.0.2-preview
Forget it! I got it! I have to change a parameter at the moment of creating the GraphServiceClient object adding the baseUrl!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.