Can't use refresh token with ASP.NET core using MS Oauth2
I have looked at a lot of questions but haven't solved the problem yet. Microsoft.AspNetCore.Authentication.MicrosoftAccount is enabled for authentication . Authentication and authorization work well. It seems inconvenient that the library will automate everything except the token update.
To update the token included offline_access
:
app.UseMicrosoftAccountAuthentication(new MicrosoftAccountOptions
{
ClientId = Startup.Config["Data:MSAppId"],
ClientSecret = Startup.Config["Data:MSAppSecret"],
CallbackPath = new PathString("/signin-microsoft-token"),
AuthorizationEndpoint = MicrosoftAccountDefaults.AuthorizationEndpoint,
SignInScheme = new IdentityCookieOptions().ExternalCookieAuthenticationScheme,
TokenEndpoint = MicrosoftAccountDefaults.TokenEndpoint,
Scope = { "openid", "email", "profile", "offline_access", "Contacts.Read", "Mail.ReadWrite", "Mail.Send" },
AutomaticAuthenticate = true,
AutomaticChallenge = true,
SaveTokens = true
});
The icons are saved in the table AspNetUserTokens
.
Using an access token, contacts and emails returned successfully, and emails are successfully sent on behalf of the user. However, when trying to use the refresh token, a Bad Request [400] is returned .
string clientId = /* ... */
string clientSecret = /* ... */
string access_token = /* ... */
string refresh_token = /* ... */
DateTime expiration_date = /* ... */
const string refreshTokenUrl = "https://login.microsoftonline.com/common/oauth2/token";
const string redirectUri = "http://localhost/";
if (DateTime.Now < (expiration_date - TimeSpan.FromMinutes(10)))
return access_token;
HttpClient client = new HttpClient();
string parameters = $"grant_type=refresh_token&refresh_token={ WebUtility.UrlEncode(refresh_token) }&client_id={ WebUtility.UrlEncode(clientId) }&client_secret={ WebUtility.UrlEncode(clientSecret) }&redirect_uri={ WebUtility.UrlEncode(redirectUri) }";
var contentBody = new StringContent(parameters, System.Text.Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage response = await client.PostAsync(refreshTokenUrl, contentBody);
if (!response.IsSuccessStatusCode)
{
// process 400 - bad request error ...
}
I looked at the request with a fiddler and it seems to be correct. I used similar code above with a pure REST solution and had no trouble.
I would have thought that their library would have a better solution for refreshing the token, as it works effortlessly for initial authentication and authorization. Is there a better way to solve this problem? If not, why is the request being rejected?
EDIT:
Removal redirect_uri
resulted in the same error response. Looking deeper at the fiddler, the error response body (JSON) begins with the following:
{
"error":"invalid_grant",
"error_description":"AADSTS70000: Transmission data parser failure: Refresh Token is malformed or invalid.
Trace ID: 92beaa67-97f9-48c3-8281-87da228b0000
// next is Correlation ID, Timestamp, trace_id, etc
However, I'm pretty sure the entire refresh_token was saved and sent correctly, with the last test having 953 characters.
source to share
No one has answered this question yet
Check out similar questions: