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"}

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,790 questions
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
13,147 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
23,413 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Marti Peig 965 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 Answers by the question author, which helps users to know the answer solved the author's problem.