Skip to content

Commit

Permalink
backward compability: handling null spOptions in handler and serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
explunit committed Feb 18, 2019
1 parent 185a709 commit 163afef
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 6 deletions.
10 changes: 5 additions & 5 deletions Sustainsys.Saml2/SAML2P/Saml2PSecurityTokenHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ namespace Sustainsys.Saml2.Saml2P
/// </summary>
public class Saml2PSecurityTokenHandler : Saml2SecurityTokenHandler
{
public Saml2PSecurityTokenHandler(SPOptions spOptions)
public Saml2PSecurityTokenHandler(): this(null)
{
if (spOptions == null)
{
throw new ArgumentNullException(nameof(spOptions));
}
// backward compatibility = null spOptions
}

public Saml2PSecurityTokenHandler(SPOptions spOptions)
{
Serializer = new Saml2PSerializer(spOptions);
}

Expand Down
2 changes: 1 addition & 1 deletion Sustainsys.Saml2/SAML2P/Saml2PSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ public override void WriteAssertion(XmlWriter writer, Saml2Assertion assertion)

protected override Saml2AuthenticationContext ReadAuthenticationContext(XmlDictionaryReader reader)
{
if (spOptions.Compatibility.IgnoreAuthenticationContextInResponse)
if (spOptions?.Compatibility?.IgnoreAuthenticationContextInResponse ?? false)
{
reader.Skip();
//hack to get around the lack of a sane constructor
Expand Down
80 changes: 80 additions & 0 deletions Tests/Tests.Shared/Saml2P/Saml2ResponseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,86 @@ public void Saml2Response_GetClaims_BadAuthnContext_IgnoredWhenConfigured()
nameidClaim.Value.Should().Be("AuthenticatedSomeone");
}

[TestMethod]
public void Saml2Response_GetClaims_HandlerWithNullOptions_AuthnContextGeneratesClaims()
{
var response =
@"<?xml version=""1.0"" encoding=""UTF-8""?>
<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol""
xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion""
ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z"">
<saml2:Issuer>https://idp.example.com</saml2:Issuer>
<saml2p:Status>
<saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" />
</saml2p:Status>
<saml2:Assertion xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion""
Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + @"_Assertion1""
IssueInstant=""2013-09-25T00:00:00Z"">
<saml2:Issuer>https://idp.example.com</saml2:Issuer>
<saml2:Subject>
<saml2:NameID>SomeOne</saml2:NameID>
<saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" />
</saml2:Subject>
<saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" />
<saml2:AuthnStatement AuthnInstant=""2013-09-25T00:00:00Z"" SessionIndex=""17"" >
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>urn:somespecialvalue</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
</saml2:Assertion>
</saml2p:Response>";

var signedResponse = SignedXmlHelper.SignXml(response);

var options = Options.FromConfiguration;
options.SPOptions.Saml2PSecurityTokenHandler = new Saml2PSecurityTokenHandler();
var result = Saml2Response.Read(signedResponse).GetClaims(options);

var authMethodClaim = result.Single().Claims.SingleOrDefault(c => c.Type == ClaimTypes.AuthenticationMethod);
authMethodClaim.Should().NotBeNull("the authentication method claim should be generated");
authMethodClaim.Value.Should().Be("urn:somespecialvalue");
}

[TestMethod]
public void Saml2Response_GetClaims_OptionsWithNullCompatibility_AuthnContextGeneratesClaims()
{
var response =
@"<?xml version=""1.0"" encoding=""UTF-8""?>
<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol""
xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion""
ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z"">
<saml2:Issuer>https://idp.example.com</saml2:Issuer>
<saml2p:Status>
<saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" />
</saml2p:Status>
<saml2:Assertion xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion""
Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + @"_Assertion1""
IssueInstant=""2013-09-25T00:00:00Z"">
<saml2:Issuer>https://idp.example.com</saml2:Issuer>
<saml2:Subject>
<saml2:NameID>SomeOne</saml2:NameID>
<saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" />
</saml2:Subject>
<saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" />
<saml2:AuthnStatement AuthnInstant=""2013-09-25T00:00:00Z"" SessionIndex=""17"" >
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>urn:somespecialvalue</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
</saml2:Assertion>
</saml2p:Response>";

var signedResponse = SignedXmlHelper.SignXml(response);

var options = StubFactory.CreateOptions();
options.SPOptions.Compatibility = null;
var result = Saml2Response.Read(signedResponse).GetClaims(options);

var authMethodClaim = result.Single().Claims.SingleOrDefault(c => c.Type == ClaimTypes.AuthenticationMethod);
authMethodClaim.Should().NotBeNull("the authentication method claim should be generated");
authMethodClaim.Value.Should().Be("urn:somespecialvalue");
}

[TestMethod]
public void Saml2Response_GetClaims_SessionIndexButNoNameId()
{
Expand Down

0 comments on commit 163afef

Please sign in to comment.