From 0a501f62f155bfd6235f33d7ad004b315afcbe99 Mon Sep 17 00:00:00 2001 From: Anders Abel Date: Wed, 27 Apr 2016 22:09:35 +0200 Subject: [PATCH] Removed Saml2REquesterId class - It's just an EntityId - Use Uri and EntityId types instead of strings. - Add nullcheck for required ProviderId property of IdpEntry. --- .../Kentor.AuthServices.Tests.csproj | 1 + .../Saml2P/Saml2AuthenticationRequestTests.cs | 32 ++++++------ .../Saml2P/Saml2IdpEntryTests.cs | 21 ++++++++ .../Kentor.AuthServices.csproj | 1 - .../SAML2P/Saml2AuthenticationRequest.cs | 10 ++-- Kentor.AuthServices/SAML2P/Saml2IdPEntry.cs | 51 ++++++++++++------- .../SAML2P/Saml2RequesterId.cs | 33 ------------ Kentor.AuthServices/SAML2P/Saml2Scoping.cs | 10 ++-- 8 files changed, 83 insertions(+), 76 deletions(-) create mode 100644 Kentor.AuthServices.Tests/Saml2P/Saml2IdpEntryTests.cs delete mode 100644 Kentor.AuthServices/SAML2P/Saml2RequesterId.cs diff --git a/Kentor.AuthServices.Tests/Kentor.AuthServices.Tests.csproj b/Kentor.AuthServices.Tests/Kentor.AuthServices.Tests.csproj index b3d329a2a..7d52aa5fa 100644 --- a/Kentor.AuthServices.Tests/Kentor.AuthServices.Tests.csproj +++ b/Kentor.AuthServices.Tests/Kentor.AuthServices.Tests.csproj @@ -129,6 +129,7 @@ + diff --git a/Kentor.AuthServices.Tests/Saml2P/Saml2AuthenticationRequestTests.cs b/Kentor.AuthServices.Tests/Saml2P/Saml2AuthenticationRequestTests.cs index 1b11ad70d..09f017164 100644 --- a/Kentor.AuthServices.Tests/Saml2P/Saml2AuthenticationRequestTests.cs +++ b/Kentor.AuthServices.Tests/Saml2P/Saml2AuthenticationRequestTests.cs @@ -7,6 +7,7 @@ using System.Xml; using Kentor.AuthServices.Saml2P; using System.Linq; +using System.IdentityModel.Metadata; namespace Kentor.AuthServices.Tests.Saml2P { @@ -237,10 +238,10 @@ public void Saml2AuthenticationRequest_ToXElement_AddsElementSaml2NameIdPolicy_F [TestMethod] public void Saml2AuthenticationRequest_ToXElement_AddsScoping() { - var requesterId = new Uri("urn://requesterid/"); - var location = "location"; + var requesterId = "urn://requesterid/"; + var location = "http://location"; var name = "name"; - var providerId = "providerId"; + var providerId = "urn:providerId"; var subject = new Saml2AuthenticationRequest() { @@ -249,23 +250,24 @@ public void Saml2AuthenticationRequest_ToXElement_AddsScoping() { ProxyCount = 5 } - .With(new Saml2IdpEntry(location, name, providerId)) - .With(new Saml2RequesterId(requesterId)) + .With(new Saml2IdpEntry(new EntityId(providerId)) + { + Name = name, + Location = new Uri(location) + }) + .WithRequesterId(new EntityId(requesterId)) }; var actual = subject.ToXElement().Element(Saml2Namespaces.Saml2P + "Scoping"); - var expected = new XElement(Saml2Namespaces.Saml2P + "root", - new XAttribute(XNamespace.Xmlns + "saml2p", Saml2Namespaces.Saml2P), - new XElement(Saml2Namespaces.Saml2P + "Scoping", - new XAttribute("ProxyCount", "5"), - new XElement(Saml2Namespaces.Saml2P + "IDPList", - new XElement(Saml2Namespaces.Saml2P + "IDPEntry", - new XAttribute("ProviderID", providerId), - new XAttribute("Name", name), + var expected = new XElement(Saml2Namespaces.Saml2P + "Scoping", + new XAttribute("ProxyCount", "5"), + new XElement(Saml2Namespaces.Saml2P + "IDPList", + new XElement(Saml2Namespaces.Saml2P + "IDPEntry", + new XAttribute("ProviderID", providerId), + new XAttribute("Name", name), new XAttribute("Loc", location))), - new XElement(Saml2Namespaces.Saml2P + "RequesterID", requesterId.ToString()))) - .Elements().Single(); + new XElement(Saml2Namespaces.Saml2P + "RequesterID", requesterId.ToString())); actual.Should().BeEquivalentTo(expected); } diff --git a/Kentor.AuthServices.Tests/Saml2P/Saml2IdpEntryTests.cs b/Kentor.AuthServices.Tests/Saml2P/Saml2IdpEntryTests.cs new file mode 100644 index 000000000..4ff4fb3bc --- /dev/null +++ b/Kentor.AuthServices.Tests/Saml2P/Saml2IdpEntryTests.cs @@ -0,0 +1,21 @@ +using FluentAssertions; +using Kentor.AuthServices.Saml2P; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IdentityModel.Metadata; + +namespace Kentor.AuthServices.Tests.Saml2P +{ + [TestClass] + public class Saml2IdpEntryTests + { + [TestMethod] + public void Saml2IdpEntry_NullCheckProviderId() + { + var subject = new Saml2IdpEntry(new EntityId("urn:foo")); + + subject.Invoking(s => s.ProviderId = null) + .ShouldThrow(); + } + } +} diff --git a/Kentor.AuthServices/Kentor.AuthServices.csproj b/Kentor.AuthServices/Kentor.AuthServices.csproj index fee33e6ec..17e008367 100644 --- a/Kentor.AuthServices/Kentor.AuthServices.csproj +++ b/Kentor.AuthServices/Kentor.AuthServices.csproj @@ -80,7 +80,6 @@ - diff --git a/Kentor.AuthServices/SAML2P/Saml2AuthenticationRequest.cs b/Kentor.AuthServices/SAML2P/Saml2AuthenticationRequest.cs index 8fa83d387..b6facc81c 100644 --- a/Kentor.AuthServices/SAML2P/Saml2AuthenticationRequest.cs +++ b/Kentor.AuthServices/SAML2P/Saml2AuthenticationRequest.cs @@ -71,7 +71,7 @@ private void AddNameIdPolicy(XElement xElement) if (NameIdPolicy != null && (NameIdPolicy.AllowCreate.HasValue || NameIdPolicy.Format != NameIdFormat.NotConfigured)) { - if(NameIdPolicy.AllowCreate.HasValue && NameIdPolicy.Format == NameIdFormat.Transient) + if (NameIdPolicy.AllowCreate.HasValue && NameIdPolicy.Format == NameIdFormat.Transient) { throw new InvalidOperationException("When NameIdPolicy/Format is set to Transient, it is not permitted to specify AllowCreate. Change Format or leave AllowCreate as null."); } @@ -167,7 +167,7 @@ public Saml2AuthenticationRequest(XmlElement xml, string relayState) allowCreate = bool.Parse(allowCreateStr); } - NameIdPolicy = new Saml2NameIdPolicy(allowCreate, nameIdFormat); + NameIdPolicy = new Saml2NameIdPolicy(allowCreate, nameIdFormat); } } @@ -182,9 +182,9 @@ public Saml2AuthenticationRequest(XmlElement xml, string relayState) public int? AttributeConsumingServiceIndex { get; set; } /// - /// Scoping for request - /// - public Saml2Scoping Scoping { get; set; } + /// Scoping for request + /// + public Saml2Scoping Scoping { get; set; } /// /// NameId policy. diff --git a/Kentor.AuthServices/SAML2P/Saml2IdPEntry.cs b/Kentor.AuthServices/SAML2P/Saml2IdPEntry.cs index 2195c29b1..56ddc25ef 100644 --- a/Kentor.AuthServices/SAML2P/Saml2IdPEntry.cs +++ b/Kentor.AuthServices/SAML2P/Saml2IdPEntry.cs @@ -1,40 +1,55 @@ -using System.Xml.Linq; +using System; +using System.IdentityModel.Metadata; +using System.Xml.Linq; namespace Kentor.AuthServices.Saml2P { /// - /// The Saml2IdPEntry specifies a single identity provider trusted by the requester to authenticate the presenter + /// The Saml2IdPEntry specifies a single identity provider trusted by the + /// requester to authenticate the presenter /// public class Saml2IdpEntry { /// /// Initializes a new instance of the class. /// - /// The location. - /// The name. /// The provider identifier. - public Saml2IdpEntry(string location, string name, string providerId) + public Saml2IdpEntry(EntityId providerId) { - Location = location; - Name = name; ProviderId = providerId; } + /// - /// Gets or sets the a URI reference representing the location of a profile-specific endpoint supporting - /// the authentication request protocol.The binding to be used must be understood from the profile of use. + /// A URI reference representing the location of a profile-specific + /// endpoint supporting the authentication request protocol. The + /// binding to be used must be understood from the profile of use. /// - /// The location. - public string Location { get; set; } + public Uri Location { get; set; } + /// - /// Gets or sets a human-readable name for the identity provider + /// A human-readable name for the identity provider. /// - /// The name. public string Name { get; set; } + + EntityId providerId; /// - /// Gets or sets the unique identifier of the identity provider. + /// The Entity Id of the Identity Provider. Cannot be null. /// - /// The provider identifier. - public string ProviderId { get; set; } + public EntityId ProviderId + { + get + { + return providerId; + } + set + { + if(value == null) + { + throw new ArgumentNullException(nameof(value)); + } + providerId = value; + } + } /// /// Create XElement for the Saml2IdPEntry. @@ -43,9 +58,9 @@ public XElement ToXElement() { var idpEntryElement = new XElement(Saml2Namespaces.Saml2P + "IDPEntry"); - idpEntryElement.AddAttributeIfNotNullOrEmpty("ProviderID", ProviderId); + idpEntryElement.AddAttributeIfNotNullOrEmpty("ProviderID", ProviderId.Id); idpEntryElement.AddAttributeIfNotNullOrEmpty("Name", Name); - idpEntryElement.AddAttributeIfNotNullOrEmpty("Loc", Location); + idpEntryElement.AddAttributeIfNotNullOrEmpty("Loc", Location.OriginalString); return idpEntryElement; } diff --git a/Kentor.AuthServices/SAML2P/Saml2RequesterId.cs b/Kentor.AuthServices/SAML2P/Saml2RequesterId.cs deleted file mode 100644 index 659dfea0e..000000000 --- a/Kentor.AuthServices/SAML2P/Saml2RequesterId.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Xml.Linq; - -namespace Kentor.AuthServices.Saml2P -{ - /// - /// Saml2RequesterId - represents a requesting entity on whose behalf the requester is acting. - /// - public class Saml2RequesterId - { - /// - /// Initializes a new instance of the class. - /// - /// The identifier. - public Saml2RequesterId(Uri id) - { - Id = id; - } - - /// - /// Gets and sets the id. - /// - public Uri Id { get; set; } - - /// - /// Create XElement for the class. - /// - public XElement ToXElement() - { - return new XElement(Saml2Namespaces.Saml2P + "RequesterID", Id); - } - } -} \ No newline at end of file diff --git a/Kentor.AuthServices/SAML2P/Saml2Scoping.cs b/Kentor.AuthServices/SAML2P/Saml2Scoping.cs index 010db0c47..da6fe5d20 100644 --- a/Kentor.AuthServices/SAML2P/Saml2Scoping.cs +++ b/Kentor.AuthServices/SAML2P/Saml2Scoping.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IdentityModel.Metadata; using System.Linq; using System.Xml.Linq; @@ -62,15 +63,15 @@ public Saml2Scoping With(Saml2IdpEntry idpEntry) /// requester is acting. Used to communicate the chain of requesters /// when proxying occurs. /// - public IList RequesterIds { get; } = new List(); + public IList RequesterIds { get; } = new List(); /// - /// Fluent config helper that adds a to the + /// Fluent config helper that adds a requester id to the /// /// /// Requester Id to add /// this - public Saml2Scoping With(Saml2RequesterId requesterId) + public Saml2Scoping WithRequesterId(EntityId requesterId) { RequesterIds.Add(requesterId); return this; @@ -97,7 +98,8 @@ public XElement ToXElement() if (RequesterIds != null && RequesterIds.Count > 0) { - scopingElement.Add(RequesterIds.Select(x => x.ToXElement())); + scopingElement.Add(RequesterIds.Select(x => + new XElement(Saml2Namespaces.Saml2P + "RequesterID", x.Id))); } return scopingElement;