Here are the changes required to get OIOSAML.Net v 1.7.6 (dk.nita.saml20) to work with a Shibboleth 2.x IDP.

Issues

  1. In OIOSAML.net the output SP metadata data has this line.
    <q1:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol" AuthnRequestsSigned="true" WantAssertionsSigned="true">
    Note the AuthnRequestSigned="true" which is hard coded to the true value in the source code but as it does not sign the AuthnRequest should be false. I changed the source code so it returns false but you may need to edit the metadata manually if you can't change the source code. 

    private void ConvertToMetadata(SAML20FederationConfig config, KeyInfo keyinfo)
    {
      // line 77 should read
      spDescriptor.AuthnRequestsSigned = XmlConvert.ToString(false); //changed to false as as code does not send signed AuthNRequests

    Update 08/07/2014  After digging into this a little further it appears that OIOSAML.Net is sending the assertion signature in the querystring if it is a binding of type Redirect which is the default. When OIOSAML.net Starts the SAML Process with the Shibboleth IDP via its url http://sp.oiosaml.net/Saml/Login.ashx?cidp=https%3a%2f%2fidp.testshib.org%2fidp%2fshibboleth&ReturnUrl=http%3a%2f%2fsp.oiosaml.net%2fSaml%2fSSO.aspx it always uses Redirect. When it does the redirect the SAMLRequest is int he querystring and so is SigAlg and Signature. Example of what was posted to TestShib in the QueryString

    1. SAMLRequest:lZJLSwMxFIX3gv8hZN9JMtPHTJhpKXZTUJRWXLhLk1sbmEnaJFP8+SZtfSAour0n55zvhlvPXrsWHcF5bU2DWUbxbHp9VR8Yn/dhZ1Zw6MEHtFw0WKtKCKpAjatCboaTalKKgpXbcTFilaKgSoye3pPymISW3vewND4IE+KIsuGAlgM6ecwLnlM+olk1rtiIjp8xWsQabUQ4uXch7D0nRKt9FqLgd3qTWfeSBmTv7Fa3QNbzu9ucrEBpBzKQ9fo+NT4I7/URGrwVrQeM4n7G8wNrcO8Mt8Jrz43owPMgeYrgEZXHzGClbXFcHqH6BO7O3t+NsQ1cgsbTBB2ZFRxZJkMH0prghAw+MxDxRNeSmpyTzy031iidvP6fTckd/fNeaTASVvGHnJZJu0hfxL9hfby+RJOfsmvySZ0OhXy7lOkb
    2. Signature:KTBOXZFV08QcC4j2jaIreqyTDJHbz6ebqxBNL6x1COF9JPeq3jYW3ZtgGc4UA8dbmMU848D9G3+SIGTTfSGRCoFn12I9q5P60yWnXpFYjnEFPn2oY0tt4aFZjtM3MyH8oXZLkeS2bV7gnensR3AbgH0yzGh6iYYUbKDwTFgx5Kc4SkCc18PobmaYcSGRNdVxIoWbk/iVA8I3APLaw7tZv6b8pqH+KIA8kdv+0RSkdcD95jugrSkK6hgpQjTVbB1mhefIuVgXxLO9nVXnvDLXPvAPI+cxvLpuqhgBMXpdvBVxpM1buGWGv59EdcHWsDikYllzBe3FCwbLv1F89UYeLQ==

     I am not sure if this is a Shibboleth thing or just the SAML IDP  I was using but they were not seeing the signature in the assertion so were rejecting the SamlRequest.  My work around was to change the OIOSAML.net source code so that the default binding could be set via the web.config.   I did this by adding a DefaultBindingMethod="POST" to the IDP <add element in the web.config then adding the DefaultBindingMethod property to the SAML20FederationConfig.cs and then changing TransferClient method in Saml20RemoteSignonHandler.cs to use the config value instead of being hard coded to SamlBinding.REDIRECT that way I can configure the default behavior for my Shibboleth IDP's to POST so the signature is present in the assertion like the IDP was expecting.

  2. In the OIOSAML.net config entry for the Shibboleth IDP I had to set the attribute omitAssertionSignatureCheck="true". The returned assertion from the Shibboleth IDP is signed but OIOSAML.net failed to find the key in metadata unless the KeyDescriptor explicitly has set use="signing". Manually editing the Shibboleth metadata and adding the <KeyDescriptor use="signing"> allowed the source code to find the key but it still failed validation. So one issue is not accepting keys from a KeyDescriptor without any use limitations, the other is failing signature validation even with the key identified. This is not a recommended production fix as by bypassing the AssertionSignatureCheck allows for fake assertions to be accepted. I double checked the OIOSAML.net source code and they are Preserving Whitespace and are using the Microsoft.net SignedXML class to check the signature and it still failes validation. It also fails validation if I use the key that is included in the SAML Response along with the assertion. I assume this is some fundamental issue with Signature creation between the two platforms but have still not found a solution to the problem.
    When I test with TestShib I get a CryptographicException SignatureDescription could not be created for the signature algorithm supplied. I believe the error with testshib is because it uses rsa-sha256 as all the other vendors I have used use rsa-sha1. When I test with another Shib IDP that uses rsa-sha1 I get a invalid Signature.

    <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="_a044a36372366e69d5b12323595cbeb6" IssueInstant="2014-08-07T23:27:29.934Z" Version="2.0"><saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://idp.testshib.org/idp/shibboleth</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></ds:SignatureMethod><ds:Reference URI="#_a044a36372366e69d5b12323595cbeb6"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"></ec:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>J2wwLDupsw3mY3Ol0AXyMIy+TKR0qnJPNoXbOKhigqQ=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>e58Bdx3B1srdyS++K2wcFMAFN2KxpBwKUzu7fwP039MXqEQvmpg+oKsmap1wk/fln6Z5KurnjKqeAyCWRcpwSB5x1zA/kuiIn77zfAKNKYx7GrU8X+LPqGMHbpo5btwkzksdKEnK0AdG8W58srB1A+BfDidAFUzTGKdhGmeO0y2DfAmsWViCJmDp6ThbfnY9j+SRkapZoRcOce9V7is2K21qJYZzA7vrqhD2CuNgjGSDs2Uy+qppMGjWW/Khbw9shs6rnuckEnM2VIYwZ0QaftLfqBZPOnzFiPonZNKpXPsjbbsY8w7j79QrIt5n6juOPqaoRyORwrfT+I45uJ57+g==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIEDjCCAvagAwIBAgIBADANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzEVMBMGA1UECBMM
    UGVubnN5bHZhbmlhMRMwEQYDVQQHEwpQaXR0c2J1cmdoMREwDwYDVQQKEwhUZXN0U2hpYjEZMBcG
    A1UEAxMQaWRwLnRlc3RzaGliLm9yZzAeFw0wNjA4MzAyMTEyMjVaFw0xNjA4MjcyMTEyMjVaMGcx
    CzAJBgNVBAYTAlVTMRUwEwYDVQQIEwxQZW5uc3lsdmFuaWExEzARBgNVBAcTClBpdHRzYnVyZ2gx
    ETAPBgNVBAoTCFRlc3RTaGliMRkwFwYDVQQDExBpZHAudGVzdHNoaWIub3JnMIIBIjANBgkqhkiG
    9w0BAQEFAAOCAQ8AMIIBCgKCAQEArYkCGuTmJp9eAOSGHwRJo1SNatB5ZOKqDM9ysg7CyVTDClcp
    u93gSP10nH4gkCZOlnESNgttg0r+MqL8tfJC6ybddEFB3YBo8PZajKSe3OQ01Ow3yT4I+Wdg1tsT
    pSge9gEz7SrC07EkYmHuPtd71CHiUaCWDv+xVfUQX0aTNPFmDixzUjoYzbGDrtAyCqA8f9CN2txI
    fJnpHE6q6CmKcoLADS4UrNPlhHSzd614kR/JYiks0K4kbRqCQF0Dv0P5Di+rEfefC6glV8ysC8dB
    5/9nb0yh/ojRuJGmgMWHgWk6h0ihjihqiu4jACovUZ7vVOCgSE5Ipn7OIwqd93zp2wIDAQABo4HE
    MIHBMB0GA1UdDgQWBBSsBQ869nh83KqZr5jArr4/7b+QazCBkQYDVR0jBIGJMIGGgBSsBQ869nh8
    3KqZr5jArr4/7b+Qa6FrpGkwZzELMAkGA1UEBhMCVVMxFTATBgNVBAgTDFBlbm5zeWx2YW5pYTET
    MBEGA1UEBxMKUGl0dHNidXJnaDERMA8GA1UEChMIVGVzdFNoaWIxGTAXBgNVBAMTEGlkcC50ZXN0
    c2hpYi5vcmeCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAjR29PhrCbk8qLN5M
    FfSVk98t3CT9jHZoYxd8QMRLI4j7iYQxXiGJTT1FXs1nd4Rha9un+LqTfeMMYqISdDDI6tv8iNpk
    OAvZZUosVkUo93pv1T0RPz35hcHHYq2yee59HJOco2bFlcsH8JBXRSRrJ3Q7Eut+z9uo80JdGNJ4
    /SJy5UorZ8KazGj16lfJhOBXldgrhppQBb0Nq6HKHguqmwRfJ+WkxemZXzhediAjGeka8nz8Jjwx
    pUjAiSWYKLtJhGEaTqCYxCCX2Dw+dOTqUzHOZ7WKv4JXPK5G/Uhr8K/qhmFT2nIQi538n6rVYLeW
    j8Bbnl+ev0peYzxFyF5sQA==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml2:Subject><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml2:SubjectConfirmationData Address="173.167.28.7" InResponseTo="id11485a84f016445284813e0ee0475a8a" NotOnOrAfter="2014-08-07T23:32:29.934Z" Recipient="http://dev1.ctmecontracts.net/Saml/login.ashx"></saml2:SubjectConfirmationData></saml2:SubjectConfirmation></saml2:Subject><saml2:Conditions NotBefore="2014-08-07T23:27:29.934Z" NotOnOrAfter="2014-08-07T23:32:29.934Z"><saml2:AudienceRestriction><saml2:Audience>http://dev1.ctmecontracts.net/Saml/</saml2:Audience></saml2:AudienceRestriction></saml2:Conditions><saml2:AuthnStatement AuthnInstant="2014-08-07T23:24:24.818Z" SessionIndex="_413103d99456d2e4a4dd3807d7f5e2ec"><saml2:SubjectLocality Address="173.167.28.7"></saml2:SubjectLocality><saml2:AuthnContext><saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef></saml2:AuthnContext></saml2:AuthnStatement><saml2:AttributeStatement><saml2:Attribute FriendlyName="uid" Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">myself</saml2:AttributeValue></saml2:Attribute><saml2:Attribute FriendlyName="eduPersonAffiliation" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Member</saml2:AttributeValue><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Staff</saml2:AttributeValue></saml2:Attribute><saml2:Attribute FriendlyName="eduPersonPrincipalName" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">myself@testshib.org</saml2:AttributeValue></saml2:Attribute><saml2:Attribute FriendlyName="sn" Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">And I</saml2:AttributeValue></saml2:Attribute><saml2:Attribute FriendlyName="eduPersonScopedAffiliation" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Member@testshib.org</saml2:AttributeValue><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Staff@testshib.org</saml2:AttributeValue></saml2:Attribute><saml2:Attribute FriendlyName="givenName" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Me Myself</saml2:AttributeValue></saml2:Attribute><saml2:Attribute FriendlyName="eduPersonEntitlement" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">urn:mace:dir:entitlement:common-lib-terms</saml2:AttributeValue></saml2:Attribute><saml2:Attribute FriendlyName="cn" Name="urn:oid:2.5.4.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Me Myself And I</saml2:AttributeValue></saml2:Attribute><saml2:Attribute FriendlyName="eduPersonTargetedID" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue><saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier="https://idp.testshib.org/idp/shibboleth" SPNameQualifier="http://dev1.ctmecontracts.net/Saml/">TY7gzp0/AiShTU7z194LQOqrZQc=</saml2:NameID></saml2:AttributeValue></saml2:Attribute><saml2:Attribute FriendlyName="telephoneNumber" Name="urn:oid:2.5.4.20" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">555-5555</saml2:AttributeValue></saml2:Attribute></saml2:AttributeStatement></saml2:Assertion>



  3. The default web.config for OIOSAML.net sample code has the NameIDFormat set to urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName which is not supported by all Shibboleth deployments (and not enabled by default). If OIOSAML.net requests a NameID format the IDP cannot satisfy the IDP may not send a NameID in the assertion's Subject at all. OIOSAML.net is coded to expect the NameID to be populated in the assertion Subject, otherwise it will throw an error.

    private void DoLogin(HttpContext context, Saml20Assertion assertion)
    {
      context.Session[IDPNameIdFormat] = assertion.Subject.Format;
      context.Session[IDPNameId] = assertion.Subject.Value;
  4. The OIOSAML.net source code is also coded to only parse metadata that has Bindings it understands so I also had to modify the metadata I received from the Shibboleth IDP to remove any unrecognized Bindings. Seems silly but when dk.nita.saml20 source code hits a binding it doesn't recognize it throws an error instead of just ignoring it. I had to remove from the Shibboleth IDP metadata any entry that wasn't Artifact, Post, Redirect or Soap to prevent it throwing an error.

    private string GetBinding(SAMLBinding samlBinding, string defaultValue)
    {
      switch (samlBinding)
      {
        case SAMLBinding.ARTIFACT:
          return Saml20Constants.ProtocolBindings.HTTP_Artifact;
        case SAMLBinding.POST:
          return Saml20Constants.ProtocolBindings.HTTP_Post;
        case SAMLBinding.REDIRECT:
          return Saml20Constants.ProtocolBindings.HTTP_Redirect;
        case SAMLBinding.SOAP :
          return Saml20Constants.ProtocolBindings.HTTP_SOAP;
        case SAMLBinding.NOT_SET:
          return defaultValue; 
        default:
          throw new ConfigurationErrorsException(String.Format("Unsupported SAML binding {0}", Enum.GetName(typeof(SAMLBinding), samlBinding)));
      } 
    }