public void LoggerFactoryIsPassedTheTypeOfTheContainingInstance() {
            var builder = new ContainerBuilder();
            builder.RegisterModule(new LoggingModule());
            builder.RegisterType<Thing>();
            var stubFactory = new StubFactory();
            builder.RegisterInstance(stubFactory).As<ILoggerFactory>();

            var container = builder.Build();
            var thing = container.Resolve<Thing>();
            Assert.That(thing.Logger, Is.Not.Null);
            Assert.That(stubFactory.CalledType, Is.EqualTo(typeof(Thing)));
        }
 public void Saml2PostBinding_Unbind_ThrowsOnNotBase64Encoded()
 {
     Saml2Binding.Get(Saml2BindingType.HttpPost)
     .Invoking(b => b.Unbind(CreateRequest("foo"), StubFactory.CreateOptions()))
     .ShouldThrow <FormatException>();
 }
        public void AcsCommand_Run_WithReturnUrl_SuccessfulResult()
        {
            var idp = Options.FromConfiguration.IdentityProviders.Default;

            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 + @""" InResponseTo = ""InResponseToId"" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z"">
                <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 + @"_Assertion2""
                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 responseFormValue = Convert.ToBase64String
                                        (Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response)));
            var relayStateFormValue = "rs1234";

            var r = new HttpRequestData(
                "POST",
                new Uri("http://localhost"),
                "/ModulePath",
                new KeyValuePair <string, string[]>[]
            {
                new KeyValuePair <string, string[]>("SAMLResponse", new string[] { responseFormValue }),
                new KeyValuePair <string, string[]>("RelayState", new string[] { relayStateFormValue })
            },
                new StoredRequestState(
                    new EntityId("https://idp.example.com"),
                    new Uri("http://localhost/testUrl.aspx"),
                    new Saml2Id("InResponseToId"),
                    null)
                );

            var ids = new ClaimsIdentity[] { new ClaimsIdentity("Federation"), new ClaimsIdentity("ClaimsAuthenticationManager") };

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

            var expected = new CommandResult()
            {
                Principal       = new ClaimsPrincipal(ids),
                HttpStatusCode  = HttpStatusCode.SeeOther,
                Location        = new Uri("http://localhost/testUrl.aspx"),
                ClearCookieName = "Kentor." + relayStateFormValue
            };

            new AcsCommand().Run(r, StubFactory.CreateOptions())
            .ShouldBeEquivalentTo(expected, opt => opt.IgnoringCyclicReferences());
        }
        public void LogoutCommand_Run_HandlesLogoutRequest_ReceivedThroughRedirectBinding()
        {
            var request = new Saml2LogoutRequest()
            {
                DestinationUrl     = new Uri("http://sp.example.com/path/AuthServices/logout"),
                Issuer             = new EntityId("https://idp.example.com"),
                SigningCertificate = SignedXmlHelper.TestCert,
                NameId             = new Saml2NameIdentifier("NameId"),
                SessionIndex       = "SessionID",
                SigningAlgorithm   = SignedXml.XmlDsigRSASHA256Url
            };

            var bindResult = Saml2Binding.Get(Saml2BindingType.HttpRedirect)
                             .Bind(request);

            var httpRequest = new HttpRequestData("GET", bindResult.Location);

            var options = StubFactory.CreateOptions();

            options.SPOptions.ServiceCertificates.Add(SignedXmlHelper.TestCert);

            CommandResult notifiedCommandResult = null;

            options.Notifications.LogoutCommandResultCreated = cr =>
            {
                notifiedCommandResult = cr;
            };

            // We're using unbind to verify the created message and UnBind
            // expects the issuer to be a known Idp for signature validation.
            // Add a dummy with the right issuer name and key.
            var dummyIdp = new IdentityProvider(options.SPOptions.EntityId, options.SPOptions);

            dummyIdp.SigningKeys.AddConfiguredKey(SignedXmlHelper.TestCert);
            options.IdentityProviders.Add(dummyIdp);

            var actual = CommandFactory.GetCommand(CommandFactory.LogoutCommandName)
                         .Run(httpRequest, options);

            var expected = new CommandResult()
            {
                HttpStatusCode        = HttpStatusCode.SeeOther,
                TerminateLocalSession = true
                                        // Deliberately not comparing Location
            };

            HttpUtility.ParseQueryString(actual.Location.Query)["Signature"]
            .Should().NotBeNull("LogoutResponse should be signed");

            actual.ShouldBeEquivalentTo(expected, opt => opt.Excluding(cr => cr.Location));
            actual.Should().BeSameAs(notifiedCommandResult);

            var actualUnbindResult = Saml2Binding.Get(Saml2BindingType.HttpRedirect)
                                     .Unbind(new HttpRequestData("GET", actual.Location), options);

            var actualMessage = actualUnbindResult.Data;

            var expectedMessage = XmlHelpers.FromString(
                $@"<samlp:LogoutResponse xmlns:samlp=""urn:oasis:names:tc:SAML:2.0:protocol""
                    xmlns=""urn:oasis:names:tc:SAML:2.0:assertion""
                    Destination=""https://idp.example.com/logout""
                    Version=""2.0"">
                    <Issuer>{options.SPOptions.EntityId.Id}</Issuer>
                    <samlp:Status>
                        <samlp:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success""/>
                    </samlp:Status>
                </samlp:LogoutResponse>").DocumentElement;

            // Set generated attributes to actual values.
            expectedMessage.SetAttribute("ID", actualMessage.GetAttribute("ID"));
            expectedMessage.SetAttribute("IssueInstant", actualMessage.GetAttribute("IssueInstant"));
            expectedMessage.SetAttribute("InResponseTo", request.Id.Value);

            actualMessage.Should().BeEquivalentTo(expectedMessage);

            actualUnbindResult.RelayState.Should().Be(request.RelayState);
            actualUnbindResult.TrustLevel.Should().Be(TrustLevel.Signature);
        }