예제 #1
0
        public SignOutMessage CreateSignoutMessage(ValidatedEndSessionRequest request)
        {
            var message = new SignOutMessage();

            if (request.Client != null)
            {
                message.ClientId = request.Client.ClientId;

                if (request.PostLogOutUri != null)
                {
                    message.ReturnUrl = request.PostLogOutUri;
                }
                else
                {
                    if (request.Client.PostLogoutRedirectUris.Any())
                    {
                        message.ReturnUrl = request.Client.PostLogoutRedirectUris.First();
                    }
                }

                if (request.State.IsPresent())
                {
                    if (message.ReturnUrl.IsPresent())
                    {
                        message.ReturnUrl = message.ReturnUrl.AddQueryString("state=" + request.State);
                    }
                }
            }

            return(message);
        }
예제 #2
0
        public EndSessionRequestValidationLog(ValidatedEndSessionRequest request)
        {
            if (request.Options.LoggingOptions.IncludeSensitiveDataInLogs)
            {
                Raw = request.Raw.ToDictionary();
            }

            SubjectId = "unknown";
            if (request.Subject != null)
            {
                var subjectClaim = request.Subject.FindFirst(Constants.ClaimTypes.Subject);
                if (subjectClaim != null)
                {
                    SubjectId = subjectClaim.Value;
                }
            }

            if (request.Client != null)
            {
                ClientId   = request.Client.ClientId;
                ClientName = request.Client.ClientName;
            }

            PostLogOutUri = request.PostLogOutUri;
            State         = request.State;
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LogoutMessage"/> class.
        /// </summary>
        /// <param name="request">The request.</param>
        public LogoutMessage(ValidatedEndSessionRequest request)
        {
            if (request != null)
            {
                if (request.Raw != null)
                {
                    Parameters = request.Raw.ToFullDictionary();
                }

                // optimize params sent to logout page, since we'd like to send them in URL (not as cookie)
                Parameters.Remove(OidcConstants.EndSessionRequest.IdTokenHint);
                Parameters.Remove(OidcConstants.EndSessionRequest.PostLogoutRedirectUri);
                Parameters.Remove(OidcConstants.EndSessionRequest.State);

                ClientId   = request.Client?.ClientId;
                ClientName = request.Client?.ClientName;
                SubjectId  = request.Subject?.GetSubjectId();
                SessionId  = request.SessionId;
                ClientIds  = request.ClientIds;

                if (request.PostLogOutUri != null)
                {
                    PostLogoutRedirectUri = request.PostLogOutUri;
                    if (request.State != null)
                    {
                        PostLogoutRedirectUri = PostLogoutRedirectUri.AddQueryString(OidcConstants.EndSessionRequest.State, request.State);
                    }
                }
            }
        }
 public LogoutMessage(ValidatedEndSessionRequest request)
 {
     if (request != null)
     {
         ClientId = request.Client?.ClientId;
         if (request.PostLogOutUri != null)
         {
             PostLogoutRedirectUri = request.PostLogOutUri;
             if (request.State != null)
             {
                 PostLogoutRedirectUri = PostLogoutRedirectUri.AddQueryString(OidcConstants.EndSessionRequest.State + "=" + request.State);
             }
         }
     }
 }
예제 #5
0
    /// <summary>
    /// Creates a result that indicates an error.
    /// </summary>
    /// <param name="message"></param>
    /// <param name="request"></param>
    /// <returns></returns>
    protected virtual EndSessionValidationResult Invalid(string message, ValidatedEndSessionRequest request = null)
    {
        message = "End session request validation failure: " + message;
        if (request != null)
        {
            var log = new EndSessionRequestValidationLog(request);
            Logger.LogInformation(message + Environment.NewLine + "{@details}", log);
        }
        else
        {
            Logger.LogInformation(message);
        }

        return(new EndSessionValidationResult
        {
            IsError = true,
            Error = "Invalid request",
            ErrorDescription = message
        });
    }
    public EndSessionRequestValidationLog(ValidatedEndSessionRequest request)
    {
        Raw = request.Raw.ToScrubbedDictionary(OidcConstants.EndSessionRequest.IdTokenHint);

        SubjectId = "unknown";

        var subjectClaim = request.Subject?.FindFirst(JwtClaimTypes.Subject);

        if (subjectClaim != null)
        {
            SubjectId = subjectClaim.Value;
        }

        if (request.Client != null)
        {
            ClientId   = request.Client.ClientId;
            ClientName = request.Client.ClientName;
        }

        PostLogOutUri = request.PostLogOutUri;
        State         = request.State;
    }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LogoutMessage"/> class.
        /// </summary>
        /// <param name="request">The request.</param>
        public LogoutMessage(ValidatedEndSessionRequest request)
        {
            if (request != null)
            {
                if (request.Raw != null)
                {
                    // optimize params sent to logout page, since we'd like to send them in URL (not as cookie)
                    var optimizationParameters = new[]
                    {
                        OidcConstants.EndSessionRequest.IdTokenHint,
                        OidcConstants.EndSessionRequest.PostLogoutRedirectUri,
                        OidcConstants.EndSessionRequest.State
                    };

                    foreach (var(key, value) in request.Raw.ToDictionary())
                    {
                        if (!Parameters.ContainsKey(key) && !optimizationParameters.Contains(key))
                        {
                            Parameters.Add(key, value);
                        }
                    }
                }

                ClientId   = request.Client?.ClientId;
                ClientName = request.Client?.ClientName;
                SubjectId  = request.Subject?.GetSubjectId();
                SessionId  = request.SessionId;
                ClientIds  = request.ClientIds;

                if (request.PostLogOutUri != null)
                {
                    PostLogoutRedirectUri = request.PostLogOutUri;
                    if (request.State != null)
                    {
                        PostLogoutRedirectUri = PostLogoutRedirectUri.AddQueryString(OidcConstants.EndSessionRequest.State, request.State);
                    }
                }
            }
        }
        public EndSessionRequestValidationLog(ValidatedEndSessionRequest request)
        {
            Raw = request.Raw.ToDictionary();

            SubjectId = "unknown";
            if (request.Subject != null)
            {
                var subjectClaim = request.Subject.FindFirst(JwtClaimTypes.Subject);
                if (subjectClaim != null)
                {
                    SubjectId = subjectClaim.Value;
                }
            }

            if (request.Client != null)
            {
                ClientId   = request.Client.ClientId;
                ClientName = request.Client.ClientName;
            }

            PostLogOutUri = request.PostLogOutUri;
            State         = request.State;
        }
예제 #9
0
    /// <summary>
    /// Logs a success result.
    /// </summary>
    /// <param name="request"></param>
    protected virtual void LogSuccess(ValidatedEndSessionRequest request)
    {
        var log = new EndSessionRequestValidationLog(request);

        Logger.LogInformation("End session request validation success" + Environment.NewLine + "{@details}", log);
    }
예제 #10
0
    /// <inheritdoc />
    public async Task <EndSessionValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject)
    {
        using var activity = Tracing.BasicActivitySource.StartActivity("EndSessionRequestValidator.Validate");

        Logger.LogDebug("Start end session request validation");

        var isAuthenticated = subject.IsAuthenticated();

        if (!isAuthenticated && Options.Authentication.RequireAuthenticatedUserForSignOutMessage)
        {
            return(Invalid("User is anonymous. Ignoring end session parameters"));
        }

        var validatedRequest = new ValidatedEndSessionRequest
        {
            Raw = parameters
        };

        var idTokenHint = parameters.Get(OidcConstants.EndSessionRequest.IdTokenHint);

        if (idTokenHint.IsPresent())
        {
            // validate id_token - no need to validate token life time
            var tokenValidationResult = await TokenValidator.ValidateIdentityTokenAsync(idTokenHint, null, false);

            if (tokenValidationResult.IsError)
            {
                return(Invalid("Error validating id token hint", validatedRequest));
            }

            validatedRequest.SetClient(tokenValidationResult.Client);

            // validate sub claim against currently logged on user
            var subClaim = tokenValidationResult.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Subject);
            if (subClaim != null && isAuthenticated)
            {
                if (subject.GetSubjectId() != subClaim.Value)
                {
                    return(Invalid("Current user does not match identity token", validatedRequest));
                }

                validatedRequest.Subject   = subject;
                validatedRequest.SessionId = await UserSession.GetSessionIdAsync();

                validatedRequest.ClientIds = await UserSession.GetClientListAsync();
            }

            var redirectUri = parameters.Get(OidcConstants.EndSessionRequest.PostLogoutRedirectUri);
            if (redirectUri.IsPresent())
            {
                if (await UriValidator.IsPostLogoutRedirectUriValidAsync(redirectUri, validatedRequest.Client))
                {
                    validatedRequest.PostLogOutUri = redirectUri;
                }
                else
                {
                    Logger.LogWarning("Invalid PostLogoutRedirectUri: {postLogoutRedirectUri}", redirectUri);
                }
            }

            if (validatedRequest.PostLogOutUri != null)
            {
                var state = parameters.Get(OidcConstants.EndSessionRequest.State);
                if (state.IsPresent())
                {
                    validatedRequest.State = state;
                }
            }
        }
        else
        {
            // no id_token to authenticate the client, but we do have a user and a user session
            validatedRequest.Subject   = subject;
            validatedRequest.SessionId = await UserSession.GetSessionIdAsync();

            validatedRequest.ClientIds = await UserSession.GetClientListAsync();
        }

        var uilocales = parameters.Get(OidcConstants.EndSessionRequest.UiLocales);

        if (uilocales.IsPresent())
        {
            if (uilocales.Length > Options.InputLengthRestrictions.UiLocale)
            {
                var log = new EndSessionRequestValidationLog(validatedRequest);
                Logger.LogWarning("UI locale too long. It will be ignored." + Environment.NewLine + "{@details}", log);
            }
            else
            {
                validatedRequest.UiLocales = uilocales;
            }
        }

        LogSuccess(validatedRequest);

        return(new EndSessionValidationResult
        {
            ValidatedRequest = validatedRequest,
            IsError = false
        });
    }