I get the below error:
{"error":"invalid_grant","error_description":"AADSTS9002313: Invalid request. Request is malformed or invalid. Trace ID: 68670f14-0eff-403c-9681-f99d5d3d5700 Correlation ID: 0f112149-c7fb-410a-b08e-6db049f63751 Timestamp: 2024-05-28 07:20:28Z","error_codes":[9002313],"timestamp":"2024-05-28 07:20:28Z","trace_id":"68670f14-0eff-403c-9681-f99d5d3d5700","correlation_id":"0f112149-c7fb-410a-b08e-6db049f63751","error_uri":"https://login.microsoftonline.com/error?code=9002313"}
Here is my current code:**
`
TokenResponse token = null;
string tokenEndPoint = "https://login.microsoftonline.com/9fa257f-...c3/oauth2/token";
string clientId = Common.ConfigWrapper.Get("OAuthClientID", "");
string clientSecret = Common.ConfigWrapper.Get("OAuthclientSecret", "");
string redirectUri = Common.ConfigWrapper.Get("OAuthRedirectUri", "");
string encodedRedirectUri = Uri.EscapeDataString(redirectUri);
// Set the request valuers.
var postData = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "authorization_code"),
new KeyValuePair<string, string>("code", code),
new KeyValuePair<string, string>("client_id", clientId),
new KeyValuePair<string, string>("client_secret", clientSecret),
new KeyValuePair<string, string>("redirect_uri", redirectUri)
};
using (var httpClient = new HttpClient())
{
HttpContent content = new FormUrlEncodedContent(postData);
using (var response = await httpClient.PostAsync(tokenEndPoint, content))
{
string responseString = await response.Content.ReadAsStringAsync();
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
token = JsonConvert.DeserializeObject<TokenResponse>(responseString);
}
else
{
// Optionally log or handle the error response
var errorResponse = JsonConvert.DeserializeObject<Dictionary<string, object>>(responseString);
Console.WriteLine($"Error: {errorResponse["error"]}, Description: {errorResponse["error_description"]}");
}
}
}
return token;
`
**Here is one of the 10 000 other wys of trying to get some type of positive result back:
In postman, I got it to work using the below, I think postman probably adds other headers which makes the post successfull, but I can't which if there are any. Any advise or help to what I am doing wrong/missing, I have been struggling for two days now. **
`
string tokenEndPoint = "https://login.microsoftonline.com/9fa27...4c3/oauth2/token";
string clientId = Common.ConfigWrapper.Get("OAuthClientID", "");
string clientSecret = Common.ConfigWrapper.Get("OAuthclientSecret", "");
string redirectUri = Common.ConfigWrapper.Get("OAuthRedirectUri", "");
string encodedRedirectUri = Uri.EscapeDataString(redirectUri);
using (var client = new HttpClient())
{
// Add headers explicitly
client.DefaultRequestHeaders.Add("Pragma", "no-cache");
client.DefaultRequestHeaders.Add("Cache-Control", "no-store, no-cache");
var requestBody = new StringContent("{ \"key\": \"value\" }", Encoding.UTF8"application/json");
var postData = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "authorization_code"),
new KeyValuePair<string, string>("code", $"{code}"),
new KeyValuePair<string, string>("redirect_uri", $"{encodedRedirectUri}"),
new KeyValuePair<string, string>("client_id", $"{clientId}"),
new KeyValuePair<string, string>("client_secret", $"{clientSecret}")
};
var content = new FormUrlEncodedContent(postData);
var response = client.PostAsync(tokenEndPoint,
new FormUrlEncodedContent(new Dictionary<string, string>()
{
{ "client_id", clientId},
{ "scope", "123"},
{ "redirect_uri", encodedRedirectUri },
{ "refresh_token", code},
{ "grant_type", "refresh_token" },
{ "client_secret", clientSecret }
})).Result;
var responseContent = response.Content.ReadAsStringAsync().Result;
if (!response.IsSuccessStatusCode)
{
responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Error: {response.StatusCode}");
Console.WriteLine($"Response: {responseContent}");
Logr.LogINF("MFA Login failed :" + responseContent);
var error = $"Token request failed. Status Code: {response.StatusCode}.";
return error;
}
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
var tokenReponse = JsonConvert.DeserializeObject<TokenResponse>(responseString);
return tokenReponse;
}``
To generate the auth-code, use the below endpoint:
https://login.microsoftonline.com/TenantID/oauth2/authorize?
&client_id=ClientID
&response_type=code
&redirect_uri=RedirectURL
&response_mode=query
&scope=offline_access User.Read
&state=12345
Modify the code to generate access and refresh tokens and to refresh the access token:
namespace OAuthExample
{
public class TokenResponse
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
}
public class OAuthClient
{
private string clientId = "ClientID";
private string clientSecret = "ClientSecret";
private string redirectUri = "https://jwt.ms";
private string tokenEndPoint = "https://login.microsoftonline.com/TenantID/oauth2/token";
public async Task<TokenResponse> GetTokenAsync(string code)
{
TokenResponse token = null;
var postData = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "authorization_code"),
new KeyValuePair<string, string>("code", code),
new KeyValuePair<string, string>("client_id", clientId),
new KeyValuePair<string, string>("client_secret", clientSecret),
new KeyValuePair<string, string>("redirect_uri", redirectUri)
};
using (var httpClient = new HttpClient())
{
HttpContent content = new FormUrlEncodedContent(postData);
using (var response = await httpClient.PostAsync(tokenEndPoint, content))
{
string responseString = await response.Content.ReadAsStringAsync();
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
token = JsonConvert.DeserializeObject<TokenResponse>(responseString);
}
else
{
var errorResponse = JsonConvert.DeserializeObject<Dictionary<string, object>>(responseString);
Console.WriteLine($"Error: {errorResponse["error"]}, Description: {errorResponse["error_description"]}");
}
}
}
return token;
}
public async Task<TokenResponse> RefreshTokenAsync(string refreshToken)
{
TokenResponse token = null;
var postData = new Dictionary<string, string>
{
{ "client_id", clientId },
{ "scope", "https://graph.microsoft.com/.default" },
{ "redirect_uri", redirectUri },
{ "refresh_token", refreshToken },
{ "grant_type", "refresh_token" },
{ "client_secret", clientSecret }
};
using (var httpClient = new HttpClient())
{
HttpContent content = new FormUrlEncodedContent(postData);
using (var response = await httpClient.PostAsync(tokenEndPoint, content))
{
string responseString = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($"Error: {response.StatusCode}");
Console.WriteLine($"Response: {responseString}");
}
else
{
token = JsonConvert.DeserializeObject<TokenResponse>(responseString);
}
}
}
return token;
}
}
class Program
{
static async Task Main(string[] args)
{
string authorizationCode = "auth-code-here";
var oauthClient = new OAuthClient();
TokenResponse token = await oauthClient.GetTokenAsync(authorizationCode);
if (token != null)
{
Console.WriteLine($"Access Token: {token.AccessToken}");
Console.WriteLine($"Token Type: {token.TokenType}");
Console.WriteLine($"Expires In: {token.ExpiresIn}");
Console.WriteLine($"Refresh Token: {token.RefreshToken}");
TokenResponse refreshedToken = await oauthClient.RefreshTokenAsync(token.RefreshToken);
if (refreshedToken != null)
{
Console.WriteLine("Refreshed Token:");
Console.WriteLine($"Access Token: {refreshedToken.AccessToken}");
Console.WriteLine($"Token Type: {refreshedToken.TokenType}");
Console.WriteLine($"Expires In: {refreshedToken.ExpiresIn}");
Console.WriteLine($"Refresh Token: {refreshedToken.RefreshToken}");
}
else
{
Console.WriteLine("Failed to refresh token.");
}
}
else
{
Console.WriteLine("Failed to obtain token.");
}
}
}
}
The access and refresh token and refreshed access and refresh token got generated successfully: