How to get a refreshtoken while working with Microsoft graph with openidconnect authentication scheme

Ariyanayagan T 0 Reputation points
2024-11-27T09:59:25.1766667+00:00

I tried to get refresh token , I got a Invalid grant error builder.Services

.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)

.AddMicrosoftIdentityWebApp(options =>

{

builder.Configuration.Bind("AzureAd", options);

options.Prompt = "select_account";

options.Events.OnTokenValidated = async context =>

{

var tokenAcquisition = context.HttpContext.RequestServices

.GetRequiredService<ITokenAcquisition>();

var graphClient = new GraphServiceClient(

new BaseBearerTokenAuthenticationProvider(

new TokenAcquisitionTokenProvider(

tokenAcquisition,

GraphConstants.Scopes,

context.Principal)));

var user = await graphClient.Me

.GetAsync(config =>

{

config.QueryParameters.Select =

["displayName", "mail", "mailboxSettings", "userPrincipalName", "id"];

});

context.Principal?.AddUserGraphInfo(user);

};

options.Events.OnAuthenticationFailed = context =>

{

var error = WebUtility.UrlEncode(context.Exception.Message);

context.Response

.Redirect($"/Home/ErrorWithMessage?message=Authentication+error&debug={error}");

context.HandleResponse();

return Task.FromResult(0);

};

options.Events.OnRemoteFailure = context =>

{

if (context.Failure is OpenIdConnectProtocolException)

{

var error = WebUtility.UrlEncode(context.Failure.Message);

context.Response

.Redirect($"/Home/ErrorWithMessage?message=Sign+in+error&debug={error}");

context.HandleResponse();

}

return Task.FromResult(0);

};

options.Events = new OpenIdConnectEvents

{

OnAuthorizationCodeReceived = async context =>

{

var tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token";

var code = context.ProtocolMessage.Code;

var clientId = context.Options.ClientId;

var clientSecret = builder.Configuration["AzureAd:ClientSecret"];

var redirectUri = context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey];

// Exchange the authorization code for tokens

var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenEndpoint);

tokenRequest.Content = new FormUrlEncodedContent(new[]

{

new KeyValuePair<string, string>("grant_type", "authorization_code"),

new KeyValuePair<string, string>("code", code),

new KeyValuePair<string, string>("redirect_uri", redirectUri),

new KeyValuePair<string, string>("client_id", clientId),

new KeyValuePair<string, string>("client_secret", clientSecret),

});

var httpClient = new HttpClient();

var tokenResponse = await httpClient.SendAsync(tokenRequest);

var tokenContent = await tokenResponse.Content.ReadAsStringAsync();

if (tokenResponse.IsSuccessStatusCode)

{

var tokenData = JsonSerializer.Deserialize<JsonElement>(tokenContent);

var accessToken = tokenData.GetProperty("access_token").GetString();

var refreshToken = tokenData.GetProperty("refresh_token").GetString();

// Save tokens securely (e.g., in a database or a secure token cache)

//SaveTokens(accessToken, refreshToken);

}

else

{

throw new Exception($"Token exchange failed: {tokenContent}");

}

}

};

})

.EnableTokenAcquisitionToCallDownstreamApi(

options =>

{

builder.Configuration.Bind("AzureAd", options);

},

GraphConstants.Scopes)

.AddMicrosoftGraph(options =>

{

options.Scopes = GraphConstants.Scopes;

})

.AddInMemoryTokenCaches();

I got a error ,

{"error":"invalid_grant","error_description":"AADSTS50148: The code_verifier does not match the code_challenge supplied in the authorization request for PKCE. Trace ID: c0ed7cbc-3a9f-4524-b754-50a398ed5f01 Correlation ID: 0b9d7f65-6932-44dd-a93a-bcb3c0c1ae24 Timestamp: 2024-11-27 09:58:39Z","error_codes":[50148],"timestamp":"2024-11-27 09:58:39Z","trace_id":"c0ed7cbc-3a9f-4524-b754-50a398ed5f01","correlation_id":"0b9d7f65-6932-44dd-a93a-bcb3c0c1ae24","error_uri":"https://login.microsoftonline.com/error?code=50148"}

Developer technologies | ASP.NET | ASP.NET Core
Microsoft Security | Microsoft Entra | Microsoft Entra ID
Microsoft Security | Microsoft Graph
{count} votes

1 answer

Sort by: Most helpful
  1. Marti Peig 975 Reputation points Microsoft Employee
    2024-11-29T10:21:01.8033333+00:00

    Hi,

    The "invalid grant" error typically occurs when there is an issue with the OAuth 2.0 authorization flow. In your code, the specific scenario most likely causing the error involves the exchange of the authorization code for access tokens.

    The error message "AADSTS50148: The code_verifier does not match the code_challenge supplied in the authorization request for PKCE" indicates a mismatch between the code_verifier and code_challenge values used in the Proof Key for Code Exchange (PKCE) flow, which is an OAuth 2.0 extension designed to improve security during authorization code exchanges. This is commonly used in mobile or public clients where storing secrets is not secure.

    Key Areas to Investigate:

    1. Ensure You Are Using PKCE Properly:
      • When you initiate the authorization request, you need to generate both a code_verifier and a code_challenge. The code_challenge is sent with the authorization request, while the code_verifier is used when exchanging the authorization code for an access token.
      • If you're not explicitly handling PKCE in your code, the Microsoft Identity Web library usually handles it for you when using AddMicrosoftIdentityWebApp(). However, it seems that you're manually implementing part of the token request logic, which might be bypassing or incorrectly handling PKCE.
    2. Check if PKCE is Supported:
      • Microsoft’s Identity platform requires PKCE by default for public clients. If you're manually implementing the token exchange process (which you are), you must ensure that the code_verifier is correctly generated and passed in the token exchange request.

    I hope it helps. Cheers

    0 comments No comments

Your answer

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