コード例 #1
0
    public async Task IsPostLogoutRedirectUriValidAsync()
    {
        (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("https://t1.api.abp.io:8080/signin-oidc", _testClient)).ShouldBeTrue();
        (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("https://api.abp.io:8080/signin-oidc", _testClient)).ShouldBeTrue();
        (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://t2.ng.abp.io/index.html", _testClient)).ShouldBeTrue();
        (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://ng.abp.io/index.html", _testClient)).ShouldBeTrue();

        (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("https://api.abp:8080/", _testClient)).ShouldBeFalse();
        (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://ng.abp.io", _testClient)).ShouldBeTrue();
        (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("https://api.t1.abp:8080/", _testClient)).ShouldBeFalse();
        (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://ng.t1.abp.io", _testClient)).ShouldBeFalse();
        (await _abpStrictRedirectUriValidator.IsPostLogoutRedirectUriValidAsync("http://t1.ng.abp.io/index.html.mydomain.com", _testClient)).ShouldBeFalse();
    }
コード例 #2
0
        private async Task <IHttpActionResult> ProcessSignOutAsync(SignOutRequestMessage msg)
        {
            if (String.IsNullOrWhiteSpace(msg.Reply))
            {
                return(RedirectToLogOut());
            }

            if (await _redirectUriValidator.IsPostLogoutRedirectUriValidAsync(msg.Reply) == false)
            {
                const string error = "invalid_signout_reply_uri";
                Logger.Error(error);
                return(BadRequest(error));
            }

            return(RedirectToLogOut(msg.Reply));
        }
コード例 #3
0
        private async Task <IHttpActionResult> ProcessSignOutAsync(SignOutRequestMessage msg)
        {
            // in order to determine redirect url wreply and wtrealm must be non-empty
            if (String.IsNullOrWhiteSpace(msg.Reply) || String.IsNullOrWhiteSpace(msg.GetParameter("wtrealm")))
            {
                return(RedirectToLogOut());
            }

            var result = await _signOutValidator.ValidateAsync(msg);

            if (result.IsError)
            {
                Logger.Error(result.Error);
                await _events.RaiseFailureWsFederationEndpointEventAsync(
                    WsFederationEventConstants.Operations.SignOut,
                    result.RelyingParty.Realm,
                    User as ClaimsPrincipal,
                    Request.RequestUri.AbsoluteUri,
                    result.Error);

                return(BadRequest(result.Error));
            }

            if (await _redirectUriValidator.IsPostLogoutRedirectUriValidAsync(msg.Reply, result.RelyingParty) == false)
            {
                const string error = "invalid_signout_reply_uri";

                Logger.Error(error);
                await _events.RaiseFailureWsFederationEndpointEventAsync(
                    WsFederationEventConstants.Operations.SignOut,
                    result.RelyingParty.Realm,
                    User as ClaimsPrincipal,
                    Request.RequestUri.AbsoluteUri,
                    error);

                return(BadRequest(error));
            }

            await _events.RaiseSuccessfulWsFederationEndpointEventAsync(
                WsFederationEventConstants.Operations.SignOut,
                result.RelyingParty.Realm,
                User as ClaimsPrincipal,
                Request.RequestUri.AbsoluteUri);

            return(RedirectToLogOut(msg.Reply));
        }
コード例 #4
0
        /// <inheritdoc />
        public async Task <EndSessionValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject)
        {
            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
                // todo: consider passing a flag to not call IsActive on the profile service? #3470
                var tokenValidationResult = await TokenValidator.ValidateIdentityTokenAsync(idTokenHint, null, false);

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

                validatedRequest.Client = 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)
                    {
                        // todo: consider not failing here and continue processing and check post logout redirect uri
                        // this would mean a change to how that's validated (and not require client validated via id_token_hint)
                        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;
                        //return Invalid("Invalid post logout URI", validatedRequest);
                    }
                    else
                    {
                        Logger.LogWarning("Invalid PostLogoutRedirectUri: {postLogoutRedirectUri}", redirectUri);
                    }
                }
                else if (validatedRequest.Client.PostLogoutRedirectUris.Count == 1)
                {
                    // todo: reconsider/remove?
                    validatedRequest.PostLogOutUri = validatedRequest.Client.PostLogoutRedirectUris.First();
                }

                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();
            }

            LogSuccess(validatedRequest);

            return(new EndSessionValidationResult
            {
                ValidatedRequest = validatedRequest,
                IsError = false
            });
        }
コード例 #5
0
        public async Task <EndSessionValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject)
        {
            _logger.LogDebug("Start end session request validation");

            var isAuthenticated = subject != null &&
                                  subject.Identity != null &&
                                  subject.Identity.IsAuthenticated;

            if (!isAuthenticated && _options.AuthenticationOptions.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.Client = 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;
                }

                var redirectUri = parameters.Get(OidcConstants.EndSessionRequest.PostLogoutRedirectUri);
                if (redirectUri.IsPresent())
                {
                    if (await _uriValidator.IsPostLogoutRedirectUriValidAsync(redirectUri, validatedRequest.Client) == false)
                    {
                        return(Invalid("Invalid post logout URI", validatedRequest));
                    }

                    validatedRequest.PostLogOutUri = redirectUri;
                }
                else if (validatedRequest.Client.PostLogoutRedirectUris.Count == 1)
                {
                    validatedRequest.PostLogOutUri = validatedRequest.Client.PostLogoutRedirectUris.First();
                }

                if (validatedRequest.PostLogOutUri != null)
                {
                    var state = parameters.Get(OidcConstants.EndSessionRequest.State);
                    if (state.IsPresent())
                    {
                        validatedRequest.State = state;
                    }
                }
            }

            LogSuccess(validatedRequest);

            return(new EndSessionValidationResult()
            {
                ValidatedRequest = validatedRequest,
                IsError = false
            });
        }
コード例 #6
0
        public async Task <ValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject)
        {
            Logger.Info("Start end session request validation");

            _validatedRequest.Raw     = parameters;
            _validatedRequest.Subject = subject;

            if (!subject.Identity.IsAuthenticated && _options.AuthenticationOptions.RequireAuthenticatedUserForSignOutMessage)
            {
                Logger.Warn("User is anonymous. Ignoring end session parameters");
                return(Invalid());
            }

            var uiLocales = parameters.Get(Constants.EndSessionRequest.UiLocales);

            if (uiLocales.IsPresent())
            {
                _validatedRequest.UiLocales = uiLocales;
            }

            var idTokenHint = parameters.Get(Constants.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)
                {
                    LogError("Error validating id token hint.");
                    return(Invalid());
                }

                _validatedRequest.Client = tokenValidationResult.Client;

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

                var redirectUri = parameters.Get(Constants.EndSessionRequest.PostLogoutRedirectUri);
                if (redirectUri.IsPresent())
                {
                    _validatedRequest.PostLogOutUri = redirectUri;

                    if (await _uriValidator.IsPostLogoutRedirectUriValidAsync(redirectUri, _validatedRequest.Client) == false)
                    {
                        LogError("Invalid post logout URI");
                        return(Invalid());
                    }

                    var state = parameters.Get(Constants.EndSessionRequest.State);
                    if (state.IsPresent())
                    {
                        _validatedRequest.State = state;
                    }
                }
            }

            LogSuccess();
            return(Valid());
        }
コード例 #7
0
        /// <inheritdoc />
        public async Task <EndSessionValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject)
        {
            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.Client = 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();
            }

            // todo: need OidcConstants.EndSession.UiLocales
            var uilocales = parameters.Get(OidcConstants.AuthorizeRequest.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
            });
        }