Skip to content

Commit

Permalink
Support for IsPassive
Browse files Browse the repository at this point in the history
- Improve ForceAuthn support
  • Loading branch information
AndersAbel committed Mar 16, 2020
2 parents b38885e + fcb9986 commit 158bb27
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 7 deletions.
17 changes: 17 additions & 0 deletions Sustainsys.Saml2/SAML2P/Saml2AuthenticationRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public XElement ToXElement()
{
x.Add(new XAttribute("ForceAuthn", ForceAuthentication));
}
if (IsPassive)
{
x.Add(new XAttribute("IsPassive", IsPassive));
}

AddNameIdPolicy(x);

Expand Down Expand Up @@ -161,6 +165,12 @@ public Saml2AuthenticationRequest(XmlElement xml, string relayState)
ForceAuthentication = bool.Parse(forceAuthnString);
}

var isPassiveString = xml.Attributes["IsPassive"].GetValueIfNotNull();
if (isPassiveString != null)
{
IsPassive = bool.Parse(isPassiveString);
}

var node = xml["NameIDPolicy", Saml2Namespaces.Saml2PName];
if (node != null)
{
Expand Down Expand Up @@ -220,5 +230,12 @@ public Saml2AuthenticationRequest(XmlElement xml, string relayState)
/// If true, the request is sent with ForceAuthn="true".
/// </summary>
public bool ForceAuthentication { get; set; } = false;

/// <summary>
/// Sets whether request should request for SAML Passive login if possible,
/// If false, the IsPassive parameter is omitted from the request.
/// If true, the request is sent with IsPassive="true".
/// </summary>
public bool IsPassive { get; set; } = false;
}
}
20 changes: 16 additions & 4 deletions Sustainsys.Saml2/WebSSO/SignInCommand.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using Sustainsys.Saml2.Configuration;
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using Sustainsys.Saml2.Configuration;
using Sustainsys.Saml2.Internal;
using Sustainsys.Saml2.Metadata;

Expand Down Expand Up @@ -144,13 +144,25 @@ private static string GetReturnUrl(HttpRequestData request, IOptions options)
: new Uri(returnPath, UriKind.RelativeOrAbsolute);

options.SPOptions.Logger.WriteInformation("Initiating login to " + idp.EntityId.Id);
return InitiateLoginToIdp(options, relayData, urls, idp, returnUrl);
return InitiateLoginToIdp(options, relayData, urls, idp, returnUrl, request);
}

private static CommandResult InitiateLoginToIdp(IOptions options, IDictionary<string, string> relayData, Saml2Urls urls, IdentityProvider idp, Uri returnUrl)
private static CommandResult InitiateLoginToIdp(IOptions options, IDictionary<string, string> relayData, Saml2Urls urls, IdentityProvider idp, Uri returnUrl, HttpRequestData request)
{
var authnRequest = idp.CreateAuthenticateRequest(urls);

var forceAuthnString = request.QueryString["ForceAuthn"].SingleOrDefault();
if (!string.IsNullOrWhiteSpace(forceAuthnString))
{
authnRequest.ForceAuthentication = bool.Parse(forceAuthnString);
}

var isPassiveString = request.QueryString["IsPassive"].SingleOrDefault();
if (!string.IsNullOrWhiteSpace(isPassiveString))
{
authnRequest.IsPassive = bool.Parse(isPassiveString);
}

options.Notifications.AuthenticationRequestCreated(authnRequest, idp, relayData);

var commandResult = idp.Bind(authnRequest);
Expand Down
46 changes: 43 additions & 3 deletions Tests/Tests.Shared/Saml2P/Saml2AuthenticationRequestTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ public void Saml2AuthenticationRequest_ForceAuthentication()
.Should().NotBeNull().And.Subject.Value.Should().Be("true");
}

[TestMethod]
public void Saml2AuthenticationRequest_IsPassive()
{
var subject = new Saml2AuthenticationRequest()
{
IsPassive = true
}.ToXElement();

subject.Should().NotBeNull().And.Subject.Attribute("IsPassive")
.Should().NotBeNull().And.Subject.Value.Should().Be("true");
}

[TestMethod]
public void Saml2AuthenticationRequest_Extensions()
{
Expand All @@ -99,6 +111,33 @@ public void Saml2AuthenticationRequest_Extensions()
public void Saml2AuthenticationRequest_Read()
{
var xmlData = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<samlp:AuthnRequest
xmlns:samlp=""urn:oasis:names:tc:SAML:2.0:protocol""
xmlns:saml=""urn:oasis:names:tc:SAML:2.0:assertion""
ID=""Saml2AuthenticationRequest_AssertionConsumerServiceUrl""
Version=""2.0""
Destination=""http://destination.example.com""
AssertionConsumerServiceURL=""https://sp.example.com/SAML2/Acs""
IssueInstant=""2004-12-05T09:21:59Z"">
<saml:Issuer>https://sp.example.com/SAML2</saml:Issuer>
/>
</samlp:AuthnRequest>
";

var relayState = "My relay state";
var subject = Saml2AuthenticationRequest.Read(xmlData, relayState);

subject.Id.Value.Should().Be("Saml2AuthenticationRequest_AssertionConsumerServiceUrl");
subject.AssertionConsumerServiceUrl.Should().Be(new Uri("https://sp.example.com/SAML2/Acs"));
subject.RelayState.Should().Be(relayState);
subject.ForceAuthentication.Should().BeFalse();
subject.IsPassive.Should().BeFalse();
}

[TestMethod]
public void Saml2AuthenticationRequest_Read_FlagsSet()
{
var xmlData = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<samlp:AuthnRequest
xmlns:samlp=""urn:oasis:names:tc:SAML:2.0:protocol""
xmlns:saml=""urn:oasis:names:tc:SAML:2.0:assertion""
Expand All @@ -107,20 +146,21 @@ public void Saml2AuthenticationRequest_Read()
Destination=""http://destination.example.com""
AssertionConsumerServiceURL=""https://sp.example.com/SAML2/Acs""
IssueInstant=""2004-12-05T09:21:59Z""
ForceAuthn=""true"">
ForceAuthn=""true""
IsPassive=""true"">
<saml:Issuer>https://sp.example.com/SAML2</saml:Issuer>
/>
</samlp:AuthnRequest>
";

var relayState = "My relay state";
var forceAuthn = true;
var subject = Saml2AuthenticationRequest.Read(xmlData, relayState);

subject.Id.Value.Should().Be("Saml2AuthenticationRequest_AssertionConsumerServiceUrl");
subject.AssertionConsumerServiceUrl.Should().Be(new Uri("https://sp.example.com/SAML2/Acs"));
subject.RelayState.Should().Be(relayState);
subject.ForceAuthentication.Should().Be(forceAuthn);
subject.ForceAuthentication.Should().BeTrue();
subject.IsPassive.Should().BeTrue();
}

[TestMethod]
Expand Down
48 changes: 48 additions & 0 deletions Tests/Tests.Shared/WebSSO/SignInCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -449,5 +449,53 @@ public void SignInCommand_WithHttpsPublicOrigin_SetsSecureCookieFlag()
actual.SetCookieName.Should().StartWith(StoredRequestState.CookieNameBase);
actual.SetCookieSecureFlag.Should().BeTrue();
}

[TestMethod]
public void SignInCommand_Run_SetIsPassiveFromQueryString()
{
var options = StubFactory.CreateOptions();
options.SPOptions.DiscoveryServiceUrl = null;

bool? isPassiveValue = null;
bool? forceAuthnValue = null;

options.Notifications.AuthenticationRequestCreated = (authnr, idp, relay) =>
{
isPassiveValue = authnr.IsPassive;
forceAuthnValue = authnr.ForceAuthentication;
};

var request = new HttpRequestData("GET",
new Uri("http://sp.example.com/Saml2/SignIn?IsPassive=true"));

SignInCommand.Run(null, null, request, options, null);

isPassiveValue.Should().BeTrue();
forceAuthnValue.Should().BeFalse();
}

[TestMethod]
public void SignInCommand_Run_SetForceAuthnFromQueryString()
{
var options = StubFactory.CreateOptions();
options.SPOptions.DiscoveryServiceUrl = null;

bool? isPassiveValue = null;
bool? forceAuthnValue = null;

options.Notifications.AuthenticationRequestCreated = (authnr, idp, relay) =>
{
isPassiveValue = authnr.IsPassive;
forceAuthnValue = authnr.ForceAuthentication;
};

var request = new HttpRequestData("GET",
new Uri("http://sp.example.com/Saml2/SignIn?ForceAuthn=true"));

SignInCommand.Run(null, null, request, options, null);

isPassiveValue.Should().BeFalse();
forceAuthnValue.Should().BeTrue();
}
}
}

0 comments on commit 158bb27

Please sign in to comment.