How to get a refreshtoken while working with Microsoft graph with openidconnect authentication scheme
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"}