예제 #1
0
    /// <inheritdoc />
    public async Task RenewAsync(string key, AuthenticationTicket ticket)
    {
        ArgumentNullException.ThrowIfNull(ticket);

        var session = await _store.GetSessionAsync(key);

        if (session == null)
        {
            throw new InvalidOperationException($"No matching item in store for key `{key}`");
        }

        _logger.LogDebug("Renewing AuthenticationTicket for key {key}, with expiration: {expiration}", key, ticket.GetExpiration());

        var sub  = ticket.GetSubjectId();
        var sid  = ticket.GetSessionId();
        var name = String.IsNullOrWhiteSpace(_options.ServerSideSessions.UserDisplayNameClaimType) ? null : ticket.Principal.FindFirst(_options.ServerSideSessions.UserDisplayNameClaimType)?.Value;

        var isNew = session.SubjectId != sub || session.SessionId != sid;

        if (isNew)
        {
            session.Created   = ticket.GetIssued();
            session.SubjectId = sub;
            session.SessionId = sid;
        }

        session.Renewed     = ticket.GetIssued();
        session.Expires     = ticket.GetExpiration();
        session.DisplayName = name;
        session.Ticket      = ticket.Serialize(_protector);

        await _store.UpdateSessionAsync(session);
    }
예제 #2
0
    /// <inheritdoc/>
    public virtual async Task <bool> ValidateSessionAsync(SessionValidationRequest request)
    {
        if (ServerSideSessionStore != null)
        {
            var shouldCoordinate =
                request.Client.CoordinateLifetimeWithUserSession == true ||
                (Options.Authentication.CoordinateClientLifetimesWithUserSession && request.Client.CoordinateLifetimeWithUserSession != false);

            if (shouldCoordinate)
            {
                var sessions = await ServerSideSessionStore.GetSessionsAsync(new SessionFilter
                {
                    SubjectId = request.SubjectId,
                    SessionId = request.SessionId
                });

                var valid = sessions.Count > 0 &&
                            sessions.Any(x => x.Expires == null || DateTime.UtcNow < x.Expires.Value);

                if (!valid)
                {
                    Logger.LogDebug("Due to missing/expired server-side session, failing token validation for subject id {subjectId} and session id {sessionId}", request.SubjectId, request.SessionId);
                    return(false);
                }

                Logger.LogDebug("Due to client token use, extending server-side session for subject id {subjectId} and session id {sessionId}", request.SubjectId, request.SessionId);

                foreach (var session in sessions)
                {
                    if (session.Expires.HasValue)
                    {
                        // setting the Expires flag on the entity (and not in the AuthenticationTicket)
                        // since we know that when loading from the DB that column will overwrite the
                        // expires in the AuthenticationTicket.
                        var diff = session.Expires.Value.Subtract(session.Renewed);
                        session.Renewed = DateTime.UtcNow;
                        session.Expires = session.Renewed.Add(diff);

                        await ServerSideSessionStore.UpdateSessionAsync(session);
                    }
                }
            }
        }

        return(true);
    }
예제 #3
0
    public async Task corrupted_server_side_session_should_logout_user()
    {
        await _pipeline.LoginAsync("bob");

        var sessions = await _sessionStore.GetSessionsAsync(new SessionFilter { SubjectId = "bob" });

        var session = await _sessionStore.GetSessionAsync(sessions.Single().Key);

        session.Ticket = "invalid";
        await _sessionStore.UpdateSessionAsync(session);

        (await IsLoggedIn()).Should().BeFalse();
        (await _sessionStore.GetSessionsAsync(new SessionFilter {
            SubjectId = "bob"
        })).Should().BeEmpty();
    }