Пример #1
0
        public async Task KentorAuthServicesAuthenticationMiddleware_SignInUrlRedirectsToIdp()
        {
            var context = OwinTestHelpers.CreateOwinContext();

            context.Request.Host = new HostString("localhost");
            var signinPath = "/AuthServices/SignIn";

            context.Request.Path        = new PathString(signinPath);
            context.Request.QueryString = new QueryString("ReturnUrl=%2FHome&idp=https%3A%2F%2Fidp2.example.com");

            var middleware = new KentorAuthServicesAuthenticationMiddleware(null, CreateAppBuilder(),
                                                                            new KentorAuthServicesAuthenticationOptions(true));

            await middleware.Invoke(context);

            context.Response.StatusCode.Should().Be(303);
            context.Response.Headers["Location"].Should().StartWith("https://idp2.example.com/idp?SAMLRequest");

            var requestId = AuthnRequestHelper.GetRequestId(new Uri(context.Response.Headers["Location"]));

            StoredRequestState storedAuthnData;

            PendingAuthnRequests.TryRemove(new Saml2Id(requestId), out storedAuthnData);

            storedAuthnData.ReturnUrl.Should().Be("http://localhost/Home");
        }
        public void PendingAuthnRequests_Remove_FalseOnIdNeverIssued()
        {
            var id = new Saml2Id();
            StoredRequestState responseData;

            PendingAuthnRequests.TryRemove(id, out responseData).Should().BeFalse();
        }
        public void PendingAuthnRequests_Remove_FalseOnIdNeverIssued()
        {
            var relayState = RelayStateGenerator.CreateSecureKey();
            StoredRequestState responseData;

            PendingAuthnRequests.TryRemove(relayState, out responseData).Should().BeFalse();
        }
Пример #4
0
        public async Task KentorAuthServicesAuthenicationMiddleware_StoresAuthenticationProperties()
        {
            var returnUrl = "http://sp.example.com/returnurl";

            var prop = new AuthenticationProperties()
            {
                RedirectUri = returnUrl
            };

            prop.Dictionary["test"] = "SomeValue";

            var middleware = new KentorAuthServicesAuthenticationMiddleware(
                new StubOwinMiddleware(401, new AuthenticationResponseChallenge(
                                           new string[] { "KentorAuthServices" }, prop)),
                CreateAppBuilder(), new KentorAuthServicesAuthenticationOptions(true));

            var context = OwinTestHelpers.CreateOwinContext();

            await middleware.Invoke(context);

            var requestId = AuthnRequestHelper.GetRequestId(new Uri(context.Response.Headers["Location"]));

            StoredRequestState storedAuthnData;

            PendingAuthnRequests.TryRemove(new Saml2Id(requestId), out storedAuthnData);

            ((AuthenticationProperties)storedAuthnData.RelayData).Dictionary["test"].Should().Be("SomeValue");
        }
Пример #5
0
        private void ValidateInResponseTo(IOptions options)
        {
            if (InResponseTo == null)
            {
                if (options.IdentityProviders[Issuer].AllowUnsolicitedAuthnResponse)
                {
                    return;
                }
                string msg = string.Format(CultureInfo.InvariantCulture,
                                           "Unsolicited responses are not allowed for idp \"{0}\".", Issuer.Id);
                throw new Saml2ResponseFailedValidationException(msg);
            }
            else
            {
                StoredRequestState storedRequestState;
                bool knownInResponseToId = PendingAuthnRequests.TryRemove(InResponseTo, out storedRequestState);
                if (!knownInResponseToId)
                {
                    string msg = string.Format(CultureInfo.InvariantCulture,
                                               "Replayed or unknown InResponseTo \"{0}\".", InResponseTo);

                    throw new Saml2ResponseFailedValidationException(msg);
                }
                requestState = storedRequestState;
                if (requestState.Idp.Id != Issuer.Id)
                {
                    var msg = string.Format(CultureInfo.InvariantCulture,
                                            "Expected response from idp \"{0}\" but received response from idp \"{1}\".",
                                            requestState.Idp.Id, issuer.Id);
                    throw new Saml2ResponseFailedValidationException(msg);
                }
            }
        }
        public void PendingAuthnRequest_TryRemove_NullGivesNull()
        {
            Saml2Id            id = null;
            StoredRequestState state;

            PendingAuthnRequests.TryRemove(id, out state).Should().BeFalse();
            state.Should().BeNull();
        }
Пример #7
0
        public void PendingAuthnRequests_Remove_FalseOnRemovedTwice()
        {
            var    id         = new Saml2Id();
            var    requestIdp = "testIdp";
            string responseIdp;

            PendingAuthnRequests.Add(id, requestIdp);
            PendingAuthnRequests.TryRemove(id, out responseIdp).Should().BeTrue();
            PendingAuthnRequests.TryRemove(id, out responseIdp).Should().BeFalse();
        }
Пример #8
0
        public void PendingAuthnRequests_Add_ThrowsOnExisting()
        {
            var id         = new Saml2Id();
            var requestIdp = "testidp";

            PendingAuthnRequests.Add(id, requestIdp);
            Action a = () => PendingAuthnRequests.Add(id, requestIdp);

            a.ShouldThrow <InvalidOperationException>();
        }
        public void PendingAuthnRequests_Add_ThrowsOnExisting()
        {
            var id          = new Saml2Id();
            var requestData = new StoredRequestState(new EntityId("testidp"), new Uri("http://localhost/Return.aspx"));

            PendingAuthnRequests.Add(id, requestData);
            Action a = () => PendingAuthnRequests.Add(id, requestData);

            a.ShouldThrow <InvalidOperationException>();
        }
Пример #10
0
        public void PendingAuthnRequests_Remove_FalseOnRemovedTwice()
        {
            var id          = new Saml2Id();
            var requestData = new StoredRequestState(new EntityId("testidp"), new Uri("http://localhost/Return.aspx"));
            StoredRequestState responseData;

            PendingAuthnRequests.Add(id, requestData);
            PendingAuthnRequests.TryRemove(id, out responseData).Should().BeTrue();
            PendingAuthnRequests.TryRemove(id, out responseData).Should().BeFalse();
        }
        private void PrepareArtifactState(string RelayState, EntityId idp)
        {
            var storedState = new StoredRequestState(
                idp,
                new Uri("http://return.org"),
                new Saml2Id(),
                null);

            PendingAuthnRequests.Add(RelayState, storedState);
        }
Пример #12
0
        public void PendingAuthnRequests_AddRemove()
        {
            var id         = new Saml2Id();
            var requestIdp = "testidp";

            PendingAuthnRequests.Add(id, requestIdp);
            string responseIdp;

            PendingAuthnRequests.TryRemove(id, out responseIdp).Should().BeTrue();
            responseIdp.Should().Be(requestIdp);
        }
Пример #13
0
        public void PendingAuthnRequests_AddRemove()
        {
            var id          = new Saml2Id();
            var requestData = new StoredRequestState("testidp", new Uri("http://localhost/Return.aspx"));

            PendingAuthnRequests.Add(id, requestData);
            StoredRequestState responseData;

            PendingAuthnRequests.TryRemove(id, out responseData).Should().BeTrue();
            responseData.Should().Be(requestData);
            responseData.Idp.Should().Be("testidp");
            responseData.ReturnUri.Should().Be("http://localhost/Return.aspx");
        }
        public void PendingAuthnRequests_Remove_FalseOnRemovedTwice()
        {
            var relayState  = RelayStateGenerator.CreateSecureKey();
            var requestData = new StoredRequestState(
                new EntityId("testidp"),
                new Uri("http://localhost/Return.aspx"),
                new Saml2Id());

            StoredRequestState responseData;

            PendingAuthnRequests.Add(relayState, requestData);
            PendingAuthnRequests.TryRemove(relayState, out responseData).Should().BeTrue();
            PendingAuthnRequests.TryRemove(relayState, out responseData).Should().BeFalse();
        }
        public void PendingAuthnRequests_AddRemove()
        {
            var relayState  = RelayStateGenerator.CreateSecureKey();
            var saml2Id     = new Saml2Id();
            var requestData = new StoredRequestState(new EntityId("testidp"), new Uri("http://localhost/Return.aspx"), saml2Id);

            PendingAuthnRequests.Add(relayState, requestData);
            StoredRequestState responseData;

            PendingAuthnRequests.TryRemove(relayState, out responseData).Should().BeTrue();
            responseData.Should().Be(requestData);
            responseData.Idp.Id.Should().Be("testidp");
            responseData.ReturnUrl.Should().Be("http://localhost/Return.aspx");
            responseData.MessageId.Should().Be(saml2Id);
        }
Пример #16
0
        public void SignInCommand_Run_MapsReturnUrl()
        {
            var defaultDestination = Options.FromConfiguration.IdentityProviders.Default.SingleSignOnServiceUrl;

            var httpRequest = new HttpRequestData("GET", new Uri("http://localhost/signin?ReturnUrl=%2FReturn.aspx"));

            var subject = new SignInCommand().Run(httpRequest, Options.FromConfiguration);

            var idp        = Options.FromConfiguration.IdentityProviders.Default;
            var relayState = HttpUtility.ParseQueryString(subject.Location.Query)["RelayState"];

            StoredRequestState storedAuthnData;

            PendingAuthnRequests.TryRemove(relayState, out storedAuthnData);

            storedAuthnData.ReturnUrl.Should().Be("http://localhost/Return.aspx");
        }
Пример #17
0
        private static IdentityProvider GetIdp(byte[] binaryArtifact, string relayState, IOptions options)
        {
            if (relayState != null)
            {
                var storedRequestState = PendingAuthnRequests.Get(relayState);
                return(options.IdentityProviders[storedRequestState.Idp]);
            }

            // It is RECOMMENDED in the spec that the first part of the artifact
            // is the SHA1 of the entity id, so let's try that as a fallback.
            var sourceId = new byte[20];

            Array.Copy(binaryArtifact, 4, sourceId, 0, 20);

            return(options.IdentityProviders.KnownIdentityProviders
                   .Single(idp => sha1.ComputeHash(
                               Encoding.UTF8.GetBytes(idp.EntityId.Id))
                           .SequenceEqual(sourceId)));
        }
Пример #18
0
        public void SignInCommand_Run_MapsReturnUrl()
        {
            var defaultDestination = Options.FromConfiguration.IdentityProviders.Default.SingleSignOnServiceUrl;

            var httpRequest = new HttpRequestData("GET", new Uri("http://localhost/signin?ReturnUrl=%2FReturn.aspx"));

            var subject = new SignInCommand().Run(httpRequest, Options.FromConfiguration);

            var idp = Options.FromConfiguration.IdentityProviders.Default;

            var authnRequest = idp.CreateAuthenticateRequest(null, StubFactory.CreateAuthServicesUrls());

            var requestId = AuthnRequestHelper.GetRequestId(subject.Location);

            StoredRequestState storedAuthnData;

            PendingAuthnRequests.TryRemove(new System.IdentityModel.Tokens.Saml2Id(requestId), out storedAuthnData);

            storedAuthnData.ReturnUrl.Should().Be("http://localhost/Return.aspx");
        }
Пример #19
0
        public void SignInCommand_Run_MapsReturnUrl()
        {
            var defaultDestination = IdentityProvider.ActiveIdentityProviders.First()
                                     .AssertionConsumerServiceUrl;

            var httpRequest = new HttpRequestData("GET", new Uri("http://localhost/signin?ReturnUrl=/Return.aspx"));

            var subject = new SignInCommand().Run(httpRequest);

            var idp = IdentityProvider.ActiveIdentityProviders.First();

            var authnRequest = idp.CreateAuthenticateRequest(null);

            var requestId = AuthnRequestHelper.GetRequestId(subject.Location);

            StoredRequestState storedAuthnData;

            PendingAuthnRequests.TryRemove(new System.IdentityModel.Tokens.Saml2Id(requestId), out storedAuthnData);

            storedAuthnData.ReturnUri.Should().Be("http://localhost/Return.aspx");
        }
Пример #20
0
        public void SignInCommand_Run_MapsReturnUrl()
        {
            var defaultDestination = IdentityProvider.ConfiguredIdentityProviders.First()
                                     .Value.DestinationUri;

            var httpRequest = Substitute.For <HttpRequestBase>();

            httpRequest["ReturnUrl"].Returns("/Return.aspx");
            httpRequest.Url.Returns(new Uri("http://localhost/signin"));
            var subject = new SignInCommand().Run(httpRequest);

            var idp = IdentityProvider.ConfiguredIdentityProviders.First().Value;

            var authnRequest = idp.CreateAuthenticateRequest(null);

            // Dig out requestId from the signincommand
            string requestId;
            var    tmp = Convert.FromBase64String(HttpUtility.UrlDecode(subject.Location.Query.Replace("?SAMLRequest=", "")));

            using (var compressed = new MemoryStream(tmp))
            {
                compressed.Seek(0, SeekOrigin.Begin);
                using (var decompressedStream = new DeflateStream(compressed, CompressionMode.Decompress))
                {
                    using (var deCompressed = new MemoryStream())
                    {
                        decompressedStream.CopyTo(deCompressed);
                        var xmlData    = System.Text.Encoding.UTF8.GetString(deCompressed.GetBuffer());
                        var requestXml = XDocument.Parse(xmlData);
                        requestId = requestXml.Document.Root.Attribute(XName.Get("ID")).Value;
                    }
                }
            }

            StoredRequestState storedAuthnData;

            PendingAuthnRequests.TryRemove(new System.IdentityModel.Tokens.Saml2Id(requestId), out storedAuthnData);

            storedAuthnData.ReturnUri.Should().Be("http://localhost/Return.aspx");
        }
Пример #21
0
        public async Task KentorAuthServicesAuthenticationMiddleware_RedirectRemembersReturnPath()
        {
            var returnUrl = "http://sp.example.com/returnurl";

            var middleware = new KentorAuthServicesAuthenticationMiddleware(
                new StubOwinMiddleware(401, new AuthenticationResponseChallenge(
                                           new string[] { "KentorAuthServices" }, new AuthenticationProperties()
            {
                RedirectUri = returnUrl
            })),
                CreateAppBuilder(), new KentorAuthServicesAuthenticationOptions(true));

            var context = OwinTestHelpers.CreateOwinContext();

            await middleware.Invoke(context);

            StoredRequestState storedAuthnData;

            PendingAuthnRequests.TryRemove(ExtractRelayState(context), out storedAuthnData);

            storedAuthnData.ReturnUrl.Should().Be(returnUrl);
        }
        public async Task KentorAuthServicesAuthenticationMiddleware_RedirectRemembersReturnPath()
        {
            var returnUri = "http://sp.example.com/returnuri";

            var middleware = new KentorAuthServicesAuthenticationMiddleware(
                new StubOwinMiddleware(401, new AuthenticationResponseChallenge(
                                           new string[] { "KentorAuthServices" }, new AuthenticationProperties()
            {
                RedirectUri = returnUri
            })),
                CreateAppBuilder(), new KentorAuthServicesAuthenticationOptions());

            var context = OwinTestHelpers.CreateOwinContext();

            await middleware.Invoke(context);

            var requestId = AuthnRequestHelper.GetRequestId(new Uri(context.Response.Headers["Location"]));

            StoredRequestState storedAuthnData;

            PendingAuthnRequests.TryRemove(new System.IdentityModel.Tokens.Saml2Id(requestId), out storedAuthnData);

            storedAuthnData.ReturnUri.Should().Be(returnUri);
        }
Пример #23
0
        public async Task KentorAuthServicesAuthenticationMiddleware_AcsWorks()
        {
            var context = OwinTestHelpers.CreateOwinContext();

            context.Request.Method = "POST";

            var state = new StoredRequestState(new EntityId("https://idp.example.com"),
                                               new Uri("http://localhost/LoggedIn"),
                                               new AuthenticationProperties());

            ((AuthenticationProperties)state.RelayData).RedirectUri        = state.ReturnUrl.OriginalString;
            ((AuthenticationProperties)state.RelayData).Dictionary["Test"] = "TestValue";

            PendingAuthnRequests.Add(new Saml2Id(MethodBase.GetCurrentMethod().Name + @"RequestID"), state);

            var response =
                @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol""
                xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion""
                ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0""
                IssueInstant=""2013-01-01T00:00:00Z"" InResponseTo=""" + MethodBase.GetCurrentMethod().Name + @"RequestID"" >
                <saml2:Issuer>
                    https://idp.example.com
                </saml2:Issuer>
                <saml2p:Status>
                    <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" />
                </saml2p:Status>
                <saml2:Assertion
                Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + @"_Assertion1""
                IssueInstant=""2013-09-25T00:00:00Z"">
                    <saml2:Issuer>https://idp.example.com</saml2:Issuer>
                    <saml2:Subject>
                        <saml2:NameID>SomeUser</saml2:NameID>
                        <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" />
                    </saml2:Subject>
                    <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" />
                </saml2:Assertion>
            </saml2p:Response>";

            var bodyData = new KeyValuePair <string, string>[] {
                new KeyValuePair <string, string>("SAMLResponse",
                                                  Convert.ToBase64String(Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response))))
            };

            var encodedBodyData = new FormUrlEncodedContent(bodyData);

            context.Request.Body        = encodedBodyData.ReadAsStreamAsync().Result;
            context.Request.ContentType = encodedBodyData.Headers.ContentType.ToString();
            context.Request.Host        = new HostString("localhost");
            context.Request.Path        = new PathString("/AuthServices/Acs");

            var signInAsAuthenticationType = "AuthType";
            var ids = new ClaimsIdentity[] { new ClaimsIdentity(signInAsAuthenticationType),
                                             new ClaimsIdentity(signInAsAuthenticationType) };

            ids[0].AddClaim(new Claim(ClaimTypes.NameIdentifier, "SomeUser", null, "https://idp.example.com"));
            ids[1].AddClaim(new Claim(ClaimTypes.Role, "RoleFromClaimsAuthManager",
                                      null, "ClaimsAuthenticationManagerStub"));

            var middleware = new KentorAuthServicesAuthenticationMiddleware(null, CreateAppBuilder(),
                                                                            StubFactory.CreateOwinOptions());

            await middleware.Invoke(context);

            context.Response.StatusCode.Should().Be(302);
            context.Response.Headers["Location"].Should().Be("http://localhost/LoggedIn");

            context.Authentication.AuthenticationResponseGrant.Principal.Identities
            .ShouldBeEquivalentTo(ids, opt => opt.IgnoringCyclicReferences());

            context.Authentication.AuthenticationResponseGrant.Properties.RedirectUri
            .Should().Be("http://localhost/LoggedIn");

            context.Authentication.AuthenticationResponseGrant.Properties.Dictionary["Test"]
            .Should().Be("TestValue");
        }