public void Saml2Binding_Bind_IsNotImplemented() { var message = new Saml2MessageImplementation(); Action a = () => new ConcreteSaml2Binding().Bind(message); a.ShouldThrow<NotImplementedException>(); }
public void Saml2PostBinding_Bind_SignsXml() { var message = new Saml2MessageImplementation { DestinationUrl = new Uri("http://www.example.com/acs"), XmlData = "<root ID=\"id\"><content>data</content></root>", MessageName = "SAMLMessageName", RelayState = "ABC1234", SigningCertificate = SignedXmlHelper.TestCert }; var signedXml = SignedXmlHelper.SignXml(message.XmlData, true); var expectedValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(signedXml)); var result = Saml2Binding.Get(Saml2BindingType.HttpPost).Bind(message); var expected = new CommandResult() { ContentType = "text/html", Content = @"<?xml version=""1.0"" encoding=""UTF-8""?> <!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.1//EN"" ""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd""> <html xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en""> <body onload=""document.forms[0].submit()""> <noscript> <p> <strong>Note:</strong> Since your browser does not support JavaScript, you must press the Continue button once to proceed. </p> </noscript> <form action=""http://www.example.com/acs"" method=""post""> <div> <input type=""hidden"" name=""RelayState"" value=""ABC1234""/> <input type=""hidden"" name=""SAMLMessageName"" value=""" + expectedValue + @"""/> </div> <noscript> <div> <input type=""submit"" value=""Continue""/> </div> </noscript> </form> </body> </html>" }; result.ShouldBeEquivalentTo(expected); }
public void Saml2RedirectBinding_Bind() { var message = new Saml2MessageImplementation { XmlData = ExampleXmlData, DestinationUrl = new Uri("http://www.example.com/sso"), MessageName = "SAMLRequest" }; var result = Saml2Binding.Get(Saml2BindingType.HttpRedirect).Bind(message); var expected = new CommandResult() { Location = new Uri("http://www.example.com/sso?SAMLRequest=" + ExampleSerializedData), HttpStatusCode = System.Net.HttpStatusCode.SeeOther, }; result.ShouldBeEquivalentTo(expected); }
public void Saml2PostBinding_Bind() { var message = new Saml2MessageImplementation { XmlData = "<root><content>data</content></root>", DestinationUrl = new Uri("http://www.example.com/acs"), MessageName = "SAMLMessageName" }; var result = Saml2Binding.Get(Saml2BindingType.HttpPost).Bind(message); var expected = new CommandResult() { ContentType = "text/html", Content = @"<?xml version=""1.0"" encoding=""UTF-8""?> <!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.1//EN"" ""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd""> <html xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en""> <body onload=""document.forms[0].submit()""> <noscript> <p> <strong>Note:</strong> Since your browser does not support JavaScript, you must press the Continue button once to proceed. </p> </noscript> <form action=""http://www.example.com/acs"" method=""post""> <div> <input type=""hidden"" name=""SAMLMessageName"" value=""PHJvb3Q+PGNvbnRlbnQ+ZGF0YTwvY29udGVudD48L3Jvb3Q+""/> </div> <noscript> <div> <input type=""submit"" value=""Continue""/> </div> </noscript> </form> </body> </html>" }; result.ShouldBeEquivalentTo(expected); }
public void LogoutCommand_Run_ThrowsOnMissingIssuerInReceivedMessage() { var msg = new Saml2MessageImplementation { MessageName = "SAMLRequest", SigningCertificate = SignedXmlHelper.TestCert, DestinationUrl = new Uri("http://localhost"), XmlData = "<Xml />" }; var url = Saml2Binding.Get(Saml2BindingType.HttpRedirect) .Bind(msg).Location; var request = new HttpRequestData("GET", url); CommandFactory.GetCommand(CommandFactory.LogoutCommandName) .Invoking(c => c.Run(request, StubFactory.CreateOptions())) .ShouldThrow <InvalidSignatureException>() .WithMessage("There is no Issuer element in the message, so there is no way to know what certificate to use to validate the signature."); }
public void Saml2RedirectBinding_Bind_AddsSignature() { var message = new Saml2MessageImplementation { XmlData = "Data", RelayState = "SomeState that needs escaping #%=3", DestinationUrl = new Uri("http://host"), MessageName = "SAMLRequest", SigningCertificate = SignedXmlHelper.TestCert }; var result = Saml2Binding.Get(Saml2BindingType.HttpRedirect).Bind(message); var query = result.Location.Query.TrimStart('?'); var split = query.Split(new[] { "&Signature=" }, StringSplitOptions.None); var signedData = split[0]; var signature = split[1]; split = signedData.Split(new[] { "SigAlg=" }, StringSplitOptions.None); var sigalg = Uri.UnescapeDataString(split[1]); var signatureDescription = (SignatureDescription)CryptoConfig.CreateFromName(sigalg); var hashAlg = signatureDescription.CreateDigest(); hashAlg.ComputeHash(Encoding.UTF8.GetBytes(signedData)); var asymmetricSignatureDeformatter = signatureDescription.CreateDeformatter( SignedXmlHelper.TestCert.PublicKey.Key); asymmetricSignatureDeformatter.VerifySignature( hashAlg, Convert.FromBase64String(signature)) .Should().BeTrue(); }
public void Saml2RedirectBinding_Bind_With_RelayState() { var message = new Saml2MessageImplementation { XmlData = "Data", RelayState = "SomeState that needs escaping #%=3", DestinationUrl = new Uri("http://host"), MessageName = "SAMLRequest" }; var expected = new CommandResult() { Location = new Uri("http://host?SAMLRequest=c0ksSQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%3D%3D" + "&RelayState=" + Uri.EscapeDataString(message.RelayState)), HttpStatusCode = System.Net.HttpStatusCode.SeeOther }; var result = Saml2Binding.Get(Saml2BindingType.HttpRedirect).Bind(message); result.ShouldBeEquivalentTo(expected); }
public void Saml2ArtifactBinding_Bind_WithoutRelayState() { var message = new Saml2MessageImplementation { DestinationUrl = new Uri("http://example.com/destination?q=a"), MessageName = "ShouldBeIgnored", XmlData = "<XML />", Issuer = new EntityId("http://idp.example.com") }; Action a = () => Saml2Binding.Get(Saml2BindingType.Artifact).Bind(message); a.ShouldNotThrow(); }
public void Saml2ArtifactBinding_Bind_WithQueryInDestination() { var message = new Saml2MessageImplementation { DestinationUrl = new Uri("http://example.com/destination?q=a"), MessageName = "ShouldBeIgnored", RelayState = "ABC123", XmlData = "<XML />", Issuer = new EntityId("http://idp.example.com") }; var result = Saml2Binding.Get(Saml2BindingType.Artifact).Bind(message); result.Location.Query.Trim('?').Contains("?").Should().BeFalse(); }
public void Saml2ArtifactBinding_Bind() { var message = new Saml2MessageImplementation { DestinationUrl = new Uri("http://example.com/destination"), MessageName = "ShouldBeIgnored", RelayState = "ABC& needs escape", XmlData = "<XML />", Issuer = new EntityId("http://idp.example.com"), }; var result = Saml2Binding.Get(Saml2BindingType.Artifact).Bind(message); var expected = new CommandResult { HttpStatusCode = HttpStatusCode.SeeOther }; result.ShouldBeEquivalentTo(expected, opt => opt.Excluding(r => r.Location)); result.Location.Query.Count(c => c == '=').Should().Be(2, "there are 2 params and = inside values should have been escaped"); var query = HttpUtility.ParseQueryString(result.Location.Query); Uri.UnescapeDataString(query["RelayState"]).Should().Be(message.RelayState); var artifact = Convert.FromBase64String( Uri.UnescapeDataString(query["SAMLart"])); ISaml2Message storedMessage; Saml2ArtifactBinding.PendingMessages.TryRemove(artifact, out storedMessage) .Should().BeTrue(); storedMessage.Should().BeSameAs(message); }
public void LogoutCommand_Run_ThrowsOnUnknownMessageRecevied() { var msg = new Saml2MessageImplementation { MessageName = "SAMLRequest", SigningCertificate = SignedXmlHelper.TestCert, DestinationUrl = new Uri("http://localhost"), XmlData = $"<Unknown><Issuer xmlns=\"{Saml2Namespaces.Saml2Name}\">https://idp.example.com</Issuer></Unknown>" }; var url = Saml2Binding.Get(Saml2BindingType.HttpRedirect) .Bind(msg).Location; var request = new HttpRequestData("GET", url); CommandFactory.GetCommand(CommandFactory.LogoutCommandName) .Invoking(c => c.Run(request, StubFactory.CreateOptions())) .ShouldThrow<NotImplementedException>(); }
public void LogoutCommand_Run_ThrowsOnMissingIssuerInReceivedMessage() { var msg = new Saml2MessageImplementation { MessageName = "SAMLRequest", SigningCertificate = SignedXmlHelper.TestCert, DestinationUrl = new Uri("http://localhost"), XmlData = "<Xml />" }; var url = Saml2Binding.Get(Saml2BindingType.HttpRedirect) .Bind(msg).Location; var request = new HttpRequestData("GET", url); CommandFactory.GetCommand(CommandFactory.LogoutCommandName) .Invoking(c => c.Run(request, StubFactory.CreateOptions())) .ShouldThrow<InvalidSignatureException>() .WithMessage("There is no Issuer element in the message, so there is no way to know what certificate to use to validate the signature."); }
private static CommandResult CreateAndBindMessageWithSignature( string issuer = "https://idp.example.com", string messageName = "SAMLRequest", bool includeRelayState = true ) { var message = new Saml2MessageImplementation { XmlData = "<Data/>", RelayState = includeRelayState ? "SomeState that needs escaping #%=3" : null, DestinationUrl = new Uri("http://host"), MessageName = messageName, SigningCertificate = SignedXmlHelper.TestCert }; if(!string.IsNullOrEmpty(issuer)) { message.XmlData = $"<Data><Issuer xmlns=\"{Saml2Namespaces.Saml2Name}\">{issuer}</Issuer></Data>"; } var result = Saml2Binding.Get(Saml2BindingType.HttpRedirect).Bind(message); return result; }