Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,54 @@ public static XmlDocument AddExtensionsAndPurposeIfNotPresent(this XmlDocument s
return samlRequest;
}

public static string GetSpidLFromExtensions(this XmlDocument samlRequest,
string extensionsElementName,
string spidLElementName)
{
if (samlRequest == null || samlRequest.DocumentElement == null)
{
return null;
}

// If the element name is prefixed, search with prefix; otherwise search only by local name
XmlNodeList extensionElements;
if (extensionsElementName.Contains(":"))
{
extensionElements = samlRequest.GetElementsByTagName(extensionsElementName);
}
else
{
extensionElements = samlRequest.GetElementsByTagName(extensionsElementName, "*");
}

if (extensionElements == null || extensionElements.Count == 0)
{
return null;
}

// Look for spidL element in the first Extensions element
XmlElement extensionsElement = extensionElements[0] as XmlElement;
if (extensionsElement != null)
{
XmlNodeList spidLElements;
if (spidLElementName.Contains(":"))
{
spidLElements = extensionsElement.GetElementsByTagName(spidLElementName);
}
else
{
spidLElements = extensionsElement.GetElementsByTagName(spidLElementName, "*");
}

if (spidLElements != null && spidLElements.Count > 0)
{
return spidLElements[0].InnerText?.Trim();
}
}

return null;
}

public static string GetSpidACSFromExtensions(this XmlDocument samlRequest,
string extensionsElementName,
string spidACSElementName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ public class SPIDOptions

public string ExtensionsElementName { get; set; } = "samlp:Extensions";
public string PurposeElementName { get; set; } = "spid:Purpose";
public string SpidLElementName { get; set; } = "ext:spidL";
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public interface ISPIDService
int GetSPIDAttributeConsumigServiceValue(NameValueCollection refererQueryString, NameValueCollection relayQueryString, NameValueCollection wctxQueryString, XmlDocument requestAsXml);
int GetCIEAttributeConsumigServiceValue(NameValueCollection refererQueryString, NameValueCollection relayQueryString, NameValueCollection wctxQueryString);

int GetSPIDLValue(NameValueCollection refererQueryString, NameValueCollection relayQueryString, NameValueCollection wctxQueryString, bool isCie);
int GetSPIDLValue(NameValueCollection refererQueryString, NameValueCollection relayQueryString, NameValueCollection wctxQueryString, bool isCie, XmlDocument requestAsXml = null);
string GetComparisonValue(NameValueCollection refererQueryString, NameValueCollection relayQueryString, NameValueCollection wctxQueryString, bool isCie);
string GetPurposeValue(NameValueCollection refererQueryString, NameValueCollection relayQueryString, NameValueCollection wctxQueryString);
bool IsSpidLValid(NameValueCollection queryStringCollection, string origin = "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ private XmlDocument SetOutcomingSAMLXmlSignIn(FederatorRequest federatorRequest,
string entityId = GetNewEntityId(federatorRequest);
requestAsXml.ChangeIssuer(entityId);

var spidL = _spidService.GetSPIDLValue(refererQueryString, relayQueryString, wctxQueryString, federatorRequest.IsCIE());
var spidL = _spidService.GetSPIDLValue(refererQueryString, relayQueryString, wctxQueryString, federatorRequest.IsCIE(), requestAsXml);
var comparison = _spidService.GetComparisonValue(refererQueryString, relayQueryString, wctxQueryString, federatorRequest.IsCIE());

//If no RequestedAuthnContext is already present, add it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,10 +267,33 @@ public int GetCIEAttributeConsumigServiceValue(NameValueCollection refererQueryS
}


public int GetSPIDLValue(NameValueCollection refererQueryString, NameValueCollection relayQueryString, NameValueCollection wctxQueryString, bool isCie)
public int GetSPIDLValue(NameValueCollection refererQueryString, NameValueCollection relayQueryString, NameValueCollection wctxQueryString, bool isCie, XmlDocument requestAsXml = null)
{
var spidL = isCie ? _cieOptions.DefaultSPIDL : _spidOptions.DefaultSPIDL;

// First, try to get spidL from SAMLRequest Extensions (highest priority)
if (requestAsXml != null)
{
try
{
var spidLFromExtensions = requestAsXml.GetSpidLFromExtensions(
_spidOptions.ExtensionsElementName,
_spidOptions.SpidLElementName);

if (!string.IsNullOrWhiteSpace(spidLFromExtensions)
&& int.TryParse(spidLFromExtensions, out int parsedValue)
&& _spidOptions.ValidSPIDL.Contains(parsedValue))
{
_logger.LogDebug("Using spidL from SAMLRequest Extensions: {spidLValue}", parsedValue);
return parsedValue;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Error extracting spidL from SAMLRequest Extensions, falling back to other methods");
}
}

if(_spidOptions.DisableSpidLevelFromReferer)
{
return spidL;
Expand Down
3 changes: 2 additions & 1 deletion WebApps/Proxy/Microsoft.SPID.Proxy/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@
"AssertionIssueInstantToleranceMins": 15,
"DisableSpidLevelFromReferer": false,
"ExtensionsElementName": "samlp:Extensions",
"PurposeElementName": "spid:Purpose"
"PurposeElementName": "spid:Purpose",
"SpidLElementName": "ext:spidL"
},
"cie": {
"DefaultSPIDL": 3,
Expand Down
Loading