/// <summary> /// Creates the refresh token. /// </summary> /// <param name="subject">The subject.</param> /// <param name="accessToken">The access token.</param> /// <param name="client">The client.</param> /// <returns> /// The refresh token handle /// </returns> public virtual async Task<string> CreateRefreshTokenAsync(ClaimsPrincipal subject, Token accessToken, Client client) { _logger.LogVerbose("Creating refresh token"); int lifetime; if (client.RefreshTokenExpiration == TokenExpiration.Absolute) { _logger.LogVerbose("Setting an absolute lifetime: " + client.AbsoluteRefreshTokenLifetime); lifetime = client.AbsoluteRefreshTokenLifetime; } else { _logger.LogVerbose("Setting a sliding lifetime: " + client.SlidingRefreshTokenLifetime); lifetime = client.SlidingRefreshTokenLifetime; } var handle = CryptoRandom.CreateUniqueId(); var refreshToken = new RefreshToken { CreationTime = DateTimeOffsetHelper.UtcNow, LifeTime = lifetime, AccessToken = accessToken, Subject = subject }; await _store.StoreAsync(handle, refreshToken); await RaiseRefreshTokenIssuedEventAsync(handle, refreshToken); return handle; }
public async Task Expired_RefreshToken() { var refreshToken = new RefreshToken { AccessToken = new Token("access_token") { Client = new Client() { ClientId = "roclient" } }, LifeTime = 10, CreationTime = DateTimeOffset.UtcNow.AddSeconds(-15) }; var handle = Guid.NewGuid().ToString(); var store = new InMemoryRefreshTokenStore(); await store.StoreAsync(handle, refreshToken); var client = await _clients.FindClientByIdAsync("roclient"); var validator = Factory.CreateTokenRequestValidator( refreshTokens: store); var parameters = new NameValueCollection(); parameters.Add(OidcConstants.TokenRequest.GrantType, "refresh_token"); parameters.Add(OidcConstants.TokenRequest.RefreshToken, handle); var result = await validator.ValidateRequestAsync(parameters, client); result.IsError.Should().BeTrue(); result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant); }
/// <summary> /// Stores the data. /// </summary> /// <param name="key">The key.</param> /// <param name="value">The value.</param> /// <returns></returns> public Task StoreAsync(string key, RefreshToken value) { _repository[key] = value; return Task.FromResult<object>(null); }
/// <summary> /// Updates the refresh token. /// </summary> /// <param name="handle">The handle.</param> /// <param name="refreshToken">The refresh token.</param> /// <param name="client">The client.</param> /// <returns> /// The refresh token handle /// </returns> public virtual async Task<string> UpdateRefreshTokenAsync(string handle, RefreshToken refreshToken, Client client) { _logger.LogVerbose("Updating refresh token"); bool needsUpdate = false; if (client.RefreshTokenUsage == TokenUsage.OneTimeOnly) { _logger.LogVerbose("Token usage is one-time only. Generating new handle"); // delete old one await _store.RemoveAsync(handle); // create new one handle = CryptoRandom.CreateUniqueId(); needsUpdate = true; } if (client.RefreshTokenExpiration == TokenExpiration.Sliding) { _logger.LogVerbose("Refresh token expiration is sliding - extending lifetime"); // make sure we don't exceed absolute exp // cap it at absolute exp var currentLifetime = refreshToken.CreationTime.GetLifetimeInSeconds(); _logger.LogVerbose("Current lifetime: " + currentLifetime.ToString()); var newLifetime = currentLifetime + client.SlidingRefreshTokenLifetime; _logger.LogVerbose("New lifetime: " + newLifetime.ToString()); if (newLifetime > client.AbsoluteRefreshTokenLifetime) { newLifetime = client.AbsoluteRefreshTokenLifetime; _logger.LogVerbose("New lifetime exceeds absolute lifetime, capping it to " + newLifetime.ToString()); } refreshToken.LifeTime = newLifetime; needsUpdate = true; } if (needsUpdate) { await _store.StoreAsync(handle, refreshToken); _logger.LogVerbose("Updated refresh token in store"); } else { _logger.LogVerbose("No updates to refresh token done"); } await RaiseRefreshTokenRefreshedEventAsync(handle, handle, refreshToken); _logger.LogVerbose("No updates to refresh token done"); return handle; }
/// <summary> /// Raises the refresh token refreshed event. /// </summary> /// <param name="oldHandle">The old handle.</param> /// <param name="newHandle">The new handle.</param> /// <param name="token">The token.</param> protected async Task RaiseRefreshTokenRefreshedEventAsync(string oldHandle, string newHandle, RefreshToken token) { await _events.RaiseSuccessfulRefreshTokenRefreshEventAsync(oldHandle, newHandle, token); }
/// <summary> /// Raises the refresh token issued event. /// </summary> /// <param name="handle">The handle.</param> /// <param name="token">The token.</param> protected async Task RaiseRefreshTokenIssuedEventAsync(string handle, RefreshToken token) { await _events.RaiseRefreshTokenIssuedEventAsync(handle, token); }
public async Task Client_has_no_OfflineAccess_Scope_anymore_at_RefreshToken_Request() { var refreshToken = new RefreshToken { AccessToken = new Token("access_token") { Client = new Client { ClientId = "roclient_restricted" }, }, LifeTime = 600, CreationTime = DateTimeOffset.UtcNow }; var handle = Guid.NewGuid().ToString(); var store = new InMemoryRefreshTokenStore(); await store.StoreAsync(handle, refreshToken); var client = await _clients.FindClientByIdAsync("roclient_restricted"); var validator = Factory.CreateTokenRequestValidator( refreshTokens: store); var parameters = new NameValueCollection(); parameters.Add(Constants.TokenRequest.GrantType, "refresh_token"); parameters.Add(Constants.TokenRequest.RefreshToken, handle); var result = await validator.ValidateRequestAsync(parameters, client); result.IsError.Should().BeTrue(); result.Error.Should().Be(Constants.TokenErrors.InvalidGrant); }