OPEN ID connect request to refresh access token

57 Views Asked by At

I'm implementing Azure Ad with Open ID connect for my web app. Intermittently, I get an expired token after logging in which causes the life time validation to fail. I think what I need is to request a refresh access token with new life time.

Here is what I have so far, on how to request it, but no luck. I have tried different end points as well, but not quite sure which on is correct. Some endpoints requires GET method not POST.

            var accessToken = await HttpContext.GetTokenAsync("access_token");
            var tokenEndpoint = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
            //tokenEndpoint = "https://login.microsoftonline.com/{myClientID}/v2.0";
            var clientId = "myClientID";
            var clientSecret = "mySecret";
            var refreshToken = await HttpContext.GetTokenAsync("refresh_token");
            
            var requestData = new[]
            {
                new KeyValuePair<string, string>("client_id", clientId),
                new KeyValuePair<string, string>("client_secret", clientSecret),
                new KeyValuePair<string, string>("grant_type", "refresh_token"),
                new KeyValuePair<string, string>("refresh_token", refreshToken),
            };

            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
                var response = await client.PostAsync(tokenEndpoint, new FormUrlEncodedContent(requestData));

                response.EnsureSuccessStatusCode();

                var json = await response.Content.ReadAsStringAsync();

            }

If this is not the correct way to requesting, what is the correct way?

2

There are 2 best solutions below

1
Kailash On BEST ANSWER

Please look at the following answers to see if it helps you:

Also, this Microsoft document provides details and examples:

You should not have to make separate calls to get access and refresh tokens, in each case you should get back both in the HTTP response body.

Also, it looks like certain versions of DotNet core have a bug:

2
Tiny Wang On

According to your code snippet, I trust you are having an asp.net core web app now, and you are trying to implement Azure Ad and you are facing token expiration issue, so that the direction of our efforts should be integrating Azure AD authentication and authorization. Here's the samples from Microsoft, we can see that we are using Microsoft.Identity.Web SDK to add the sign-in module and using Microsoft.Identity.Web.TokenAcquisition to generate token for hitting external API which is secured by AAD. This shall be the "correct" way you are seeking. The samples might use old .net version and nuget packages, this might bring some differences if you are using .net 8 and latest nuget packages.

We shall have codes like this in web app,

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
    .AddInMemoryTokenCaches();

and codes like below for web api project.

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
    .AddInMemoryTokenCaches();