diff --git a/src/ITfoxtec.Identity.Saml2.Mvc/ITfoxtec.Identity.Saml2.Mvc.csproj b/src/ITfoxtec.Identity.Saml2.Mvc/ITfoxtec.Identity.Saml2.Mvc.csproj
index a520be5..27fc6a6 100644
--- a/src/ITfoxtec.Identity.Saml2.Mvc/ITfoxtec.Identity.Saml2.Mvc.csproj
+++ b/src/ITfoxtec.Identity.Saml2.Mvc/ITfoxtec.Identity.Saml2.Mvc.csproj
@@ -26,10 +26,10 @@ Support the Danish NemLog-in 2 / OIOSAML 2 and NemLog-in 3 / OIOSAML 3.SAML SAML 2.0 SAML2.0 SAML2 SAML 2 SAML-P SAMLP SSO Identity Provider (IdP) and Relying Party (RP) Authentication Metadata OIOSAML OIOSAML 2 OIOSAML 3 NemLogin NemLog-in 2 NemLog-in 3 ASP.NET MVC
en-US
https://itfoxtec.com/favicon.ico
- 4.10.8.0
- 4.10.8.0
+ 4.10.9.1
+ 4.10.9.1
Copyright © 2023
- 4.10.8.0
+ 4.10.9-beta1
true
ITfoxtec.SAML2.snk
false
diff --git a/src/ITfoxtec.Identity.Saml2.MvcCore/ITfoxtec.Identity.Saml2.MvcCore.csproj b/src/ITfoxtec.Identity.Saml2.MvcCore/ITfoxtec.Identity.Saml2.MvcCore.csproj
index a85490b..be88200 100644
--- a/src/ITfoxtec.Identity.Saml2.MvcCore/ITfoxtec.Identity.Saml2.MvcCore.csproj
+++ b/src/ITfoxtec.Identity.Saml2.MvcCore/ITfoxtec.Identity.Saml2.MvcCore.csproj
@@ -31,10 +31,10 @@ Support the Danish NemLog-in 2 / OIOSAML 2 and NemLog-in 3 / OIOSAML 3.SAML SAML 2.0 SAML2.0 SAML2 SAML 2 SAML-P SAMLP SSO Identity Provider (IdP) Relying Party (RP) Authentication Metadata OIOSAML OIOSAML 2 OIOSAML 3 NemLogin NemLog-in 2 NemLog-in 3 ASP.NET MVC Core
en-US
https://itfoxtec.com/favicon.ico
- 4.10.8.0
- 4.10.8.0
+ 4.10.9.1
+ 4.10.9.1
Copyright © 2023
- 4.10.8.0
+ 4.10.9-beta1
true
ITfoxtec.SAML2.snk
false
diff --git a/src/ITfoxtec.Identity.Saml2/Bindings/Saml2ArtifactBinding.cs b/src/ITfoxtec.Identity.Saml2/Bindings/Saml2ArtifactBinding.cs
index 1c90dd7..e83b334 100644
--- a/src/ITfoxtec.Identity.Saml2/Bindings/Saml2ArtifactBinding.cs
+++ b/src/ITfoxtec.Identity.Saml2/Bindings/Saml2ArtifactBinding.cs
@@ -22,7 +22,7 @@ public Saml2ArtifactBinding()
CertificateIncludeOption = X509IncludeOption.EndCertOnly;
}
- protected internal override void BindInternal(Saml2Request saml2Request, string messageName)
+ protected override void BindInternal(Saml2Request saml2Request, string messageName)
{
if (!(saml2Request is Saml2ArtifactResolve saml2ArtifactResolve))
throw new ArgumentException("Only Saml2ArtifactResolve is supported");
diff --git a/src/ITfoxtec.Identity.Saml2/Bindings/Saml2Binding.cs b/src/ITfoxtec.Identity.Saml2/Bindings/Saml2Binding.cs
index 040543d..71537a7 100644
--- a/src/ITfoxtec.Identity.Saml2/Bindings/Saml2Binding.cs
+++ b/src/ITfoxtec.Identity.Saml2/Bindings/Saml2Binding.cs
@@ -28,7 +28,7 @@ public abstract class Saml2Binding
public Saml2Binding()
{ }
- protected internal virtual void BindInternal(Saml2Request saml2RequestResponse, bool createXml = true)
+ protected virtual void BindInternal(Saml2Request saml2RequestResponse, bool createXml = true)
{
if (saml2RequestResponse == null)
throw new ArgumentNullException(nameof(saml2RequestResponse));
@@ -54,7 +54,12 @@ protected internal virtual void BindInternal(Saml2Request saml2RequestResponse,
}
}
- protected internal abstract void BindInternal(Saml2Request saml2RequestResponse, string messageName);
+ internal void ApplyBinding(Saml2Request saml2RequestResponse, string messageName)
+ {
+ BindInternal(saml2RequestResponse, messageName);
+ }
+
+ protected abstract void BindInternal(Saml2Request saml2RequestResponse, string messageName);
public Saml2Request Unbind(HttpRequest request, Saml2Request saml2Request)
{
diff --git a/src/ITfoxtec.Identity.Saml2/Bindings/Saml2PostBinding.cs b/src/ITfoxtec.Identity.Saml2/Bindings/Saml2PostBinding.cs
index 272c5ab..798f687 100644
--- a/src/ITfoxtec.Identity.Saml2/Bindings/Saml2PostBinding.cs
+++ b/src/ITfoxtec.Identity.Saml2/Bindings/Saml2PostBinding.cs
@@ -28,7 +28,7 @@ public Saml2PostBinding()
CertificateIncludeOption = X509IncludeOption.EndCertOnly;
}
- protected internal override void BindInternal(Saml2Request saml2RequestResponse, string messageName)
+ protected override void BindInternal(Saml2Request saml2RequestResponse, string messageName)
{
BindInternal(saml2RequestResponse);
diff --git a/src/ITfoxtec.Identity.Saml2/Bindings/Saml2RedirectBinding.cs b/src/ITfoxtec.Identity.Saml2/Bindings/Saml2RedirectBinding.cs
index a5f0ebe..24aece1 100644
--- a/src/ITfoxtec.Identity.Saml2/Bindings/Saml2RedirectBinding.cs
+++ b/src/ITfoxtec.Identity.Saml2/Bindings/Saml2RedirectBinding.cs
@@ -19,7 +19,7 @@ public class Saml2RedirectBinding : Saml2Binding
public string Signature { get; protected set; }
- protected internal override void BindInternal(Saml2Request saml2RequestResponse, string messageName)
+ protected override void BindInternal(Saml2Request saml2RequestResponse, string messageName)
{
base.BindInternal(saml2RequestResponse);
diff --git a/src/ITfoxtec.Identity.Saml2/Bindings/Saml2SoapEnvelope.cs b/src/ITfoxtec.Identity.Saml2/Bindings/Saml2SoapEnvelope.cs
index 7e75f4e..2991746 100644
--- a/src/ITfoxtec.Identity.Saml2/Bindings/Saml2SoapEnvelope.cs
+++ b/src/ITfoxtec.Identity.Saml2/Bindings/Saml2SoapEnvelope.cs
@@ -21,7 +21,7 @@ public class Saml2SoapEnvelope : Saml2Binding
///
public string SoapResponseXml { get; set; }
- protected internal override void BindInternal(Saml2Request saml2Request, string messageName)
+ protected override void BindInternal(Saml2Request saml2Request, string messageName)
{
if (!(saml2Request is Saml2ArtifactResponse))
throw new ArgumentException("Only Saml2ArtifactResponse is supported");
diff --git a/src/ITfoxtec.Identity.Saml2/Claims/Saml2ClaimTypes.cs b/src/ITfoxtec.Identity.Saml2/Claims/Saml2ClaimTypes.cs
index 5002db3..391157b 100644
--- a/src/ITfoxtec.Identity.Saml2/Claims/Saml2ClaimTypes.cs
+++ b/src/ITfoxtec.Identity.Saml2/Claims/Saml2ClaimTypes.cs
@@ -5,6 +5,8 @@ public static class Saml2ClaimTypes
{
public const string NameId = "http://schemas.itfoxtec.com/ws/2014/02/identity/claims/saml2nameid";
public const string NameIdFormat = "http://schemas.itfoxtec.com/ws/2014/02/identity/claims/saml2nameidformat";
+ public const string NameQualifier = "http://schemas.itfoxtec.com/ws/2014/02/identity/claims/saml2namequalifier";
+ public const string SPNameQualifier = "http://schemas.itfoxtec.com/ws/2014/02/identity/claims/saml2spnamequalifier";
public const string SessionIndex = "http://schemas.itfoxtec.com/ws/2014/02/identity/claims/saml2sessionindex";
}
}
diff --git a/src/ITfoxtec.Identity.Saml2/Extensions/Saml2BindingExtensions.cs b/src/ITfoxtec.Identity.Saml2/Extensions/Saml2BindingExtensions.cs
index 96db960..6dc67a3 100644
--- a/src/ITfoxtec.Identity.Saml2/Extensions/Saml2BindingExtensions.cs
+++ b/src/ITfoxtec.Identity.Saml2/Extensions/Saml2BindingExtensions.cs
@@ -10,19 +10,19 @@ public static class Saml2BindingExtensions
{
public static T Bind(this T binding, Saml2Request saml2Request) where T : Saml2Binding
{
- binding.BindInternal(saml2Request, Saml2Constants.Message.SamlRequest);
+ binding.ApplyBinding(saml2Request, Saml2Constants.Message.SamlRequest);
return binding;
}
public static T Bind(this T binding, Saml2Response saml2Response) where T : Saml2Binding
{
- binding.BindInternal(saml2Response, Saml2Constants.Message.SamlResponse);
+ binding.ApplyBinding(saml2Response, Saml2Constants.Message.SamlResponse);
return binding;
}
public static T Bind(this T binding, Saml2ArtifactResolve saml2ArtifactResolve) where T : Saml2Binding
{
- binding.BindInternal(saml2ArtifactResolve, Saml2Constants.Message.SamlArt);
+ binding.ApplyBinding(saml2ArtifactResolve, Saml2Constants.Message.SamlArt);
return binding;
}
diff --git a/src/ITfoxtec.Identity.Saml2/ITfoxtec.Identity.Saml2.csproj b/src/ITfoxtec.Identity.Saml2/ITfoxtec.Identity.Saml2.csproj
index 724574b..da0fbc1 100644
--- a/src/ITfoxtec.Identity.Saml2/ITfoxtec.Identity.Saml2.csproj
+++ b/src/ITfoxtec.Identity.Saml2/ITfoxtec.Identity.Saml2.csproj
@@ -32,10 +32,10 @@ Support the Danish NemLog-in 2 / OIOSAML 2 and NemLog-in 3 / OIOSAML 3.SAML SAML 2.0 SAML2.0 SAML2 SAML 2 SAML-P SAMLP SSO Identity Provider (IdP) Relying Party (RP) Authentication Metadata OIOSAML OIOSAML 2 OIOSAML 3 NemLogin NemLog-in 2 NemLog-in 3
en-US
https://itfoxtec.com/favicon.ico
- 4.10.8.0
- 4.10.8.0
+ 4.10.9.1
+ 4.10.9.1
Copyright © 2023
- 4.10.8.0
+ 4.10.9-beta1
true
ITfoxtec.SAML2.snk
false
diff --git a/src/ITfoxtec.Identity.Saml2/Request/Saml2AuthnRequest.cs b/src/ITfoxtec.Identity.Saml2/Request/Saml2AuthnRequest.cs
index 2e30b23..e9d27a0 100644
--- a/src/ITfoxtec.Identity.Saml2/Request/Saml2AuthnRequest.cs
+++ b/src/ITfoxtec.Identity.Saml2/Request/Saml2AuthnRequest.cs
@@ -112,10 +112,19 @@ public class Saml2AuthnRequest : Saml2Request
///
/// [Optional]
/// If present, specifies an Audience
- /// Part of the OIOSAML standard used for conditions on request.
+ /// Specifies the SAML conditions the requester expects to limit the validity and/or use of the resulting
+ /// assertion(s).
///
public Condition Conditions { get; set; }
+ ///
+ /// [Optional]
+ /// Specifies a set of identity providers trusted by the requester to authenticate the presenter, as well as
+ /// limitations and context related to proxying of the <AuthnRequest> message to subsequent identity
+ /// providers by the responder.
+ ///
+ public Scoping Scoping { get; set; }
+
public Saml2AuthnRequest(Saml2Configuration config) : base(config)
{
if (config == null) throw new ArgumentNullException(nameof(config));
@@ -185,6 +194,11 @@ protected override IEnumerable GetXContent()
{
yield return RequestedAuthnContext.ToXElement();
}
+
+ if (Scoping != null)
+ {
+ yield return Scoping.ToXElement();
+ }
}
protected internal override void Read(string xml, bool validate = false, bool detectReplayedTokens = true)
@@ -208,6 +222,8 @@ protected internal override void Read(string xml, bool validate = false, bool de
NameIdPolicy = XmlDocument.DocumentElement[Saml2Constants.Message.NameIdPolicy, Saml2Constants.ProtocolNamespace.OriginalString].GetElementOrNull();
RequestedAuthnContext = XmlDocument.DocumentElement[Saml2Constants.Message.RequestedAuthnContext, Saml2Constants.ProtocolNamespace.OriginalString].GetElementOrNull();
+
+ Scoping = XmlDocument.DocumentElement[Saml2Constants.Message.Scoping, Saml2Constants.ProtocolNamespace.OriginalString].GetElementOrNull();
}
protected override void ValidateElementName()
diff --git a/src/ITfoxtec.Identity.Saml2/Request/Saml2AuthnResponse.cs b/src/ITfoxtec.Identity.Saml2/Request/Saml2AuthnResponse.cs
index 93f34df..e3d69c8 100644
--- a/src/ITfoxtec.Identity.Saml2/Request/Saml2AuthnResponse.cs
+++ b/src/ITfoxtec.Identity.Saml2/Request/Saml2AuthnResponse.cs
@@ -284,7 +284,7 @@ protected override XmlElement GetAssertionElement()
return assertionElementCache;
}
- private XmlElement GetAssertionElementReference()
+ protected XmlElement GetAssertionElementReference()
{
var assertionElements = XmlDocument.DocumentElement.SelectNodes($"//*[local-name()='{Schemas.Saml2Constants.Message.Assertion}']");
if (assertionElements.Count != 1)
diff --git a/src/ITfoxtec.Identity.Saml2/Request/Saml2LogoutRequest.cs b/src/ITfoxtec.Identity.Saml2/Request/Saml2LogoutRequest.cs
index bbb1d01..e984fc4 100644
--- a/src/ITfoxtec.Identity.Saml2/Request/Saml2LogoutRequest.cs
+++ b/src/ITfoxtec.Identity.Saml2/Request/Saml2LogoutRequest.cs
@@ -57,6 +57,16 @@ public Saml2LogoutRequest(Saml2Configuration config, ClaimsPrincipal currentPrin
NameId = new Saml2NameIdentifier(ReadClaimValue(identity, Saml2ClaimTypes.NameId), new Uri(nameIdFormat));
}
+ var nameIdNameQualifier = ReadClaimValue(identity, Saml2ClaimTypes.NameQualifier, false);
+ if (!string.IsNullOrEmpty(nameIdNameQualifier))
+ {
+ NameId.NameQualifier = nameIdNameQualifier;
+ }
+ var nameIdSPNameQualifier = ReadClaimValue(identity, Saml2ClaimTypes.SPNameQualifier, false);
+ if (!string.IsNullOrEmpty(nameIdSPNameQualifier))
+ {
+ NameId.SPNameQualifier = nameIdSPNameQualifier;
+ }
SessionIndex = ReadClaimValue(identity, Saml2ClaimTypes.SessionIndex, false);
}
}
@@ -103,15 +113,20 @@ protected override IEnumerable GetXContent()
if (NameId != null)
{
- object[] nameIdContent;
+ var nameIdContent = new List