public async Task DeleteUserSessionsAsync_for_valid_sub_should_succeed() { await _subject.CreateUserSessionAsync(new UserSession { Key = Guid.NewGuid().ToString(), Ticket = "ticket", SubjectId = "sub1", SessionId = "sid1_1", }); await _subject.CreateUserSessionAsync(new UserSession { Key = Guid.NewGuid().ToString(), Ticket = "ticket", SubjectId = "sub1", SessionId = "sid1_2", }); await _subject.CreateUserSessionAsync(new UserSession { Key = Guid.NewGuid().ToString(), Ticket = "ticket", SubjectId = "sub2", SessionId = "sid2_1", }); await _subject.CreateUserSessionAsync(new UserSession { Key = Guid.NewGuid().ToString(), Ticket = "ticket", SubjectId = "sub2", SessionId = "sid2_2", }); await _subject.CreateUserSessionAsync(new UserSession { Key = Guid.NewGuid().ToString(), Ticket = "ticket", SubjectId = "sub2", SessionId = "sid2_3", }); await _subject.CreateUserSessionAsync(new UserSession { Key = Guid.NewGuid().ToString(), Ticket = "ticket", SubjectId = "sub3", SessionId = "sid3_1", }); await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub2" }); _database.UserSessions.Count().Should().Be(3); _database.UserSessions.Count(x => x.SubjectId == "sub2").Should().Be(0); }
/// <inheritdoc /> public async Task <string> StoreAsync(AuthenticationTicket ticket) { // it's possible that the user re-triggered OIDC (somehow) prior to // the session DB records being cleaned up, so we should preemptively remove // conflicting session records for this sub/sid combination await _store.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = ticket.GetSubjectId(), SessionId = ticket.GetSessionId() }); var key = CryptoRandom.CreateUniqueId(format: CryptoRandom.OutputFormat.Hex); _logger.LogDebug("Creating entry in store for AuthenticationTicket, key {key}, with expiration: {expiration}", key, ticket.GetExpiration()); var session = new UserSession { Key = key, Created = ticket.GetIssued(), Renewed = ticket.GetIssued(), Expires = ticket.GetExpiration(), SubjectId = ticket.GetSubjectId(), SessionId = ticket.GetSessionId(), Ticket = ticket.Serialize(_protector) }; await _store.CreateUserSessionAsync(session); return(key); }
/// <inheritdoc/> public async Task RevokeSessionsAsync(UserSessionsFilter filter, CancellationToken cancellationToken = default) { if (_options.BackchannelLogoutAllUserSessions) { filter.SessionId = null; } if (_options.RevokeRefreshTokenOnLogout) { var tickets = await _ticketStore.GetUserTicketsAsync(filter); if (tickets?.Any() == true) { foreach (var ticket in tickets) { var refreshToken = ticket.Properties.GetTokenValue("refresh_token"); if (!String.IsNullOrWhiteSpace(refreshToken)) { var response = await _tokenEndpoint.RevokeRefreshTokenAsync(refreshToken); if (response.IsError) { _logger.LogDebug("Error revoking refresh token: {error} for subject id: {sub} and session id: {sid}", response.Error, ticket.GetSubjectId(), ticket.GetSessionId()); } else { _logger.LogDebug("Refresh token revoked successfully for subject id: {sub} and session id: {sid}", ticket.GetSubjectId(), ticket.GetSessionId()); } } } } } await _sessionStore.DeleteUserSessionsAsync(filter); }