public FederatedSignoutMiddlewareTests()
        {
            _user     = IdentityServerPrincipal.Create("bob", "bob", new Claim(JwtClaimTypes.SessionId, "123"));
            _pipeline = new MockIdSvrUiPipeline();

            _pipeline.Users.Add(new InMemoryUser
            {
                Subject  = "bob",
                Username = "******",
                Claims   = new Claim[]
                {
                    new Claim("name", "Bob Loblaw"),
                    new Claim("email", "*****@*****.**"),
                    new Claim("role", "Attorney"),
                }
            });

            _pipeline.FederatedSignOut = async ctx =>
            {
                _idSvrIFrameUrl = await ctx.GetIdentityServerSignoutFrameCallbackUrlAsync();

                ISessionIdService sessionId = ctx.RequestServices.GetRequiredService <ISessionIdService>();
                _idSvrSid = await sessionId.GetCurrentSessionIdAsync();
            };
            _pipeline.Initialize();
            _pipeline.Options.AuthenticationOptions.FederatedSignOutPaths.Add(MockIdSvrUiPipeline.FederatedSignOutPath);
        }
Esempio n. 2
0
        /// <summary>
        /// Ensures the client list cookie.
        /// </summary>
        /// <param name="sid">The sid.</param>
        /// <returns></returns>
        public async Task EnsureClientListCookieAsync(string sid)
        {
            if (await _sessionId.GetCurrentSessionIdAsync() == sid)
            {
                var value = await GetPropertyValueAsync();

                SetCookie(sid, value);
            }
        }
Esempio n. 3
0
        public async Task <string> CreateLogoutContextAsync()
        {
            var sid = await _sessionIdService.GetCurrentSessionIdAsync();

            if (sid != null)
            {
                await _clientSessionService.EnsureClientListCookieAsync(sid);

                var msg = new MessageWithId <LogoutMessage>(new LogoutMessage {
                    SessionId = sid
                });

                var id = msg.Id;
                await _logoutMessageStore.WriteAsync(id, msg);

                return(id);
            }

            return(null);
        }
        private async Task <AuthorizeRequestValidationResult> ValidateOptionalParametersAsync(ValidatedAuthorizeRequest request)
        {
            //////////////////////////////////////////////////////////
            // check nonce
            //////////////////////////////////////////////////////////
            var nonce = request.Raw.Get(OidcConstants.AuthorizeRequest.Nonce);

            if (nonce.IsPresent())
            {
                if (nonce.Length > _options.InputLengthRestrictions.Nonce)
                {
                    LogError("Nonce too long", request);
                    return(Invalid(request));
                }

                request.Nonce = nonce;
            }
            else
            {
                if (request.GrantType == GrantType.Implicit ||
                    request.GrantType == GrantType.Hybrid)
                {
                    // only openid requests require nonce
                    if (request.IsOpenIdRequest)
                    {
                        LogError("Nonce required for implicit and hybrid flow with openid scope", request);
                        return(Invalid(request));
                    }
                }
            }


            //////////////////////////////////////////////////////////
            // check prompt
            //////////////////////////////////////////////////////////
            var prompt = request.Raw.Get(OidcConstants.AuthorizeRequest.Prompt);

            if (prompt.IsPresent())
            {
                if (Constants.SupportedPromptModes.Contains(prompt))
                {
                    request.PromptMode = prompt;
                }
                else
                {
                    _logger.LogDebug("Unsupported prompt mode - ignored: " + prompt);
                }
            }

            //////////////////////////////////////////////////////////
            // check ui locales
            //////////////////////////////////////////////////////////
            var uilocales = request.Raw.Get(OidcConstants.AuthorizeRequest.UiLocales);

            if (uilocales.IsPresent())
            {
                if (uilocales.Length > _options.InputLengthRestrictions.UiLocale)
                {
                    LogError("UI locale too long", request);
                    return(Invalid(request));
                }

                request.UiLocales = uilocales;
            }

            //////////////////////////////////////////////////////////
            // check display
            //////////////////////////////////////////////////////////
            var display = request.Raw.Get(OidcConstants.AuthorizeRequest.Display);

            if (display.IsPresent())
            {
                if (Constants.SupportedDisplayModes.Contains(display))
                {
                    request.DisplayMode = display;
                }

                _logger.LogDebug("Unsupported display mode - ignored: " + display);
            }

            //////////////////////////////////////////////////////////
            // check max_age
            //////////////////////////////////////////////////////////
            var maxAge = request.Raw.Get(OidcConstants.AuthorizeRequest.MaxAge);

            if (maxAge.IsPresent())
            {
                int seconds;
                if (int.TryParse(maxAge, out seconds))
                {
                    if (seconds >= 0)
                    {
                        request.MaxAge = seconds;
                    }
                    else
                    {
                        LogError("Invalid max_age.", request);
                        return(Invalid(request));
                    }
                }
                else
                {
                    LogError("Invalid max_age.", request);
                    return(Invalid(request));
                }
            }

            //////////////////////////////////////////////////////////
            // check login_hint
            //////////////////////////////////////////////////////////
            var loginHint = request.Raw.Get(OidcConstants.AuthorizeRequest.LoginHint);

            if (loginHint.IsPresent())
            {
                if (loginHint.Length > _options.InputLengthRestrictions.LoginHint)
                {
                    LogError("Login hint too long", request);
                    return(Invalid(request));
                }

                request.LoginHint = loginHint;
            }

            //////////////////////////////////////////////////////////
            // check acr_values
            //////////////////////////////////////////////////////////
            var acrValues = request.Raw.Get(OidcConstants.AuthorizeRequest.AcrValues);

            if (acrValues.IsPresent())
            {
                if (acrValues.Length > _options.InputLengthRestrictions.AcrValues)
                {
                    LogError("Acr values too long", request);
                    return(Invalid(request));
                }

                request.AuthenticationContextReferenceClasses = acrValues.FromSpaceSeparatedString().Distinct().ToList();
            }

            //////////////////////////////////////////////////////////
            // check custom acr_values: idp
            //////////////////////////////////////////////////////////
            var idp = request.GetIdP();

            if (idp.IsPresent())
            {
                // if idp is present but client does not allow it, strip it from the request message
                if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any())
                {
                    if (!request.Client.IdentityProviderRestrictions.Contains(idp))
                    {
                        _logger.LogWarning("idp requested ({idp}) is not in client restriction list.", idp);
                        request.RemoveIdP();
                    }
                }
            }

            //////////////////////////////////////////////////////////
            // check session cookie
            //////////////////////////////////////////////////////////
            if (_options.Endpoints.EnableCheckSessionEndpoint &&
                request.Subject.Identity.IsAuthenticated)
            {
                var sessionId = await _sessionId.GetCurrentSessionIdAsync();

                if (sessionId.IsPresent())
                {
                    request.SessionId = sessionId;
                }
                else
                {
                    LogError("Check session endpoint enabled, but SessionId is missing", request);
                }
            }

            return(Valid(request));
        }
Esempio n. 5
0
        public async Task <EndSessionValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject)
        {
            _logger.LogDebug("Start end session request validation");

            var isAuthenticated = subject.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;
                    validatedRequest.SessionId = await _sessionId.GetCurrentSessionIdAsync();
                }

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