How do I refresh a Cognito token after the accessToken has expired #221
-
I am testing behaviour where:
var user = await _cognitoUserManager
.FindByEmailAsync(loginModel.UserName);
if (user == null)
{
return BadRequest("Invalid Username or Password");
}
var result = await _cognitoSignInManager.CheckPasswordSignInAsync(
user,
loginModel.Password,
false);
if (result.Succeeded)
{
return Ok(new
{
Token = user.SessionTokens.AccessToken,
RefreshToken = user.SessionTokens.RefreshToken
});
} This allows me to return the access token and the refresh token to the Angular front-end where it is stored in LocalStorage. I set the access token expiry to 5 mins and the refresh token expiry to 30 mins. However I notice that a call to: HttpContext.User.Identity.IsAuthenticated returns false. Does this mean that I have to authenticate the user myself by calling
Now my problem is getting the refreshed access token. I can get the sub of the user from the access token and then I can retrieve the user using this call: var user = await _cognitoUserManager
.FindByIdAsync(sub); but the user's SessionTokens is null (as the access token has expired?). Thus a subsequent call to: await _cognitoSignInManager.RefreshSignInAsync(user); fails. Now I could go through this sequence of calls: var request = new AdminInitiateAuthRequest()
{
AuthFlow = AuthFlowType.REFRESH_TOKEN_AUTH,
AuthParameters = new Dictionary<string, string>()
{
{ "REFRESH_TOKEN", refreshToken },
{ "SECRET_HASH", _configuration["AWS:UserPoolClientSecret"] },
},
ClientId = _configuration["AWS:UserPoolClientId"],
UserPoolId = _configuration["AWS:UserPoolId"],
};
var result = await _amazonCognitoIdentityProvider
.AdminInitiateAuthAsync(request);
if (result.HttpStatusCode == System.Net.HttpStatusCode.OK)
{
var newAccessToken = result.AuthenticationResult.AccessToken;
var newRefreshToken = refreshToken;
return new ObjectResult(new
{
accessToken = newAccessToken,
refreshToken = newRefreshToken
});
} but this does not refresh my CognitoUser? BTW, I also have this code in my Startup.cs: services.AddAuthentication()
.AddJwtBearer(options =>
{
options.TokenValidationParameters = GetCognitoTokenValidationParams();
});
...
private TokenValidationParameters GetCognitoTokenValidationParams()
{
var cognitoIssuer = $"https://cognito-idp.{Configuration["AWS:Region"]}.amazonaws.com/{Configuration["AWS:UserPoolId"]}";
var jwtKeySetUrl = $"{cognitoIssuer}/.well-known/jwks.json";
var cognitoAudience = Configuration["AWS:UserPoolClientId"];
return new TokenValidationParameters
{
IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
{
// get JsonWebKeySet from AWS
var json = new WebClient().DownloadString(jwtKeySetUrl);
// serialize the result
var keys = JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;
// cast the result to be the type expected by IssuerSigningKeyResolver
return (IEnumerable<SecurityKey>)keys;
},
ValidIssuer = cognitoIssuer,
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidAudience = cognitoAudience
};
} What is the pattern I should follow here? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
Hi @IgorPietraszko, Good morning. Could you please confirm the version of Thanks, |
Beta Was this translation helpful? Give feedback.
-
Hello! Reopening this discussion to make it searchable. |
Beta Was this translation helpful? Give feedback.
Hi @IgorPietraszko,
Good morning.
Could you please confirm the version of
Amazon.AspNetCore.Identity.Cognito
package being used? Also, you may follow the sample at https://github.com/aws/aws-aspnet-cognito-identity-provider/tree/master/samples, refresh token should be present in user claims and you should be able to use refresh token auth flow. Also refer #122 (comment) which explains how the session cookie expiration time is set.Thanks,
Ashish