Auth0 Home Blog Docs

Auth0.AuthenticationApi .NET - Using AuthenticationApiClient to refresh token

.net
refresh-tokens
authenticationapi

#1

I’m trying to use the AuthenticationApiClient to use the refreshtoken.

    using Auth0.AuthenticationApi;
    using Auth0.AuthenticationApi.Models;
    
    var authenticationApiClient = new AuthenticationApiClient(new Uri(new Uri("https://YOUR_AUTH0_DOMAIN")));
    
    var authenticationResponse = await authenticationApiClient.GetTokenAsync(new RefreshTokenRequest
    {
        ClientId = "my client id",
        RefreshToken = "my refresh token"
    });

I see it’s calling the /oauth/token end correctly (I see in my Logs that a ‘Success Exchange’ was made for ‘Refresh Token for Access Token’), but in my application, the process never seems to complete, and I’m unable to get the ‘refreshed’ token.

Is there something I’m doing incorrectly?


#2

Can you confirm what version of the SDK you are using? Also, you seem to be missing a few parameters for the RefreshTokenRequest:
http://auth0.github.io/auth0.net/api/Auth0.AuthenticationApi.Models.RefreshTokenRequest.html


#3

Hi, I’m using the latest stable version from NuGet 4.2.0.

According to https://auth0.com/docs/api/authentication#refresh-token , only the client_id and refresh_token? My Token Endpoint Authentication Method for my client is set to ‘None’, so I’m not passing in my client_secret. I assume that the API adds the other grant_type=refresh_token.


#4

With that exact same code and targeting my own Auth0 account I could not reproduce this situation in a console application. If you haven’t done so already I would also recommend you to do the test in a completely new console application with just that code. This will help in identifying the possible source of the issue; for your convenience, here’s the full sample code I used in my console test:

static void Main(string] args) {
    ExecuteRefreshTokenGrant();

    Console.ReadKey(intercept: true);
}

static async void ExecuteRefreshTokenGrant() {
    var client = new AuthenticationApiClient("[domain]");

    await client.GetTokenAsync(new RefreshTokenRequest {
        ClientId = "...",
        RefreshToken = "..."
    });

    Console.WriteLine("Response received!");

The above prints the response received message as expected. If in your situation and for your account it also does the same this suggests that something specific to your application is causing the issue. The use of await implies that the logic will try to resume where you were, more specifically, if you start the async call on a Windows Forms UI thread the code after the await should run on the same UI thread.

The fact that await takes in consideration any existing synchronization context results that the outcome is not the same depending on where you run the code. On a console application there’s no synchronization context so the code after await will just run on thread pool thread. However, if you do this as part of an ASP.NET request then it will try to execute the code on the original request thread and this sometimes leads to unexpected blocked requests because you then explicitly waited on a task that was not completed blocking the ASP.NET request thread and that task will only complete after executing some additional code in that same thread so this ends up in a deadlock scenario that would explain why you see the log of a successful exchange, but your application never completes the processing.

If you’re doing this as part of ASP.NET, check the answer on the following SO question for more relevant information on this subject (the .NET SDK uses HttpClient so the question is even more relevant):

https://stackoverflow.com/questions/10343632/httpclient-getasync-never-returns-when-using-await-async


#5

You’re absolutely right-- I don’t know why I didn’t think to strip it down and test it on a simple console. I actually caught a mistake from my domain value, but I could definitely get my refreshed token with your code.

Thank you for the other resources! I believe the way I’m calling the code is definitely leading to some unintended deadlock.


#6