iDP连接到SP SAML / SSO

时间:2017-11-12 12:47:47

标签: c# .net model-view-controller saml-2.0 idp

我被分配了一个任务,我(iDP)需要连接到服务提供商。

到目前为止,我有代码:

public ActionResult SSO(string SAMLRequest)
{
    var model = new ApiSsoModel();

    try
    {
        if (SAMLRequest == null)
            throw new ArgumentNullException("The parameter \"SAMLRequest\" is null.");

        byte[] decoded2 = Convert.FromBase64String(SAMLRequest);
        string decoded3 = string.Empty;

        using (MemoryStream stream2 = new MemoryStream(decoded2))
        {
            using (MemoryStream stream3 = new MemoryStream())
            {
                using (StreamReader reader3 = new StreamReader(stream3))
                {
                    stream2.Position = 0L;
                    new DeflateStream(stream2, CompressionMode.Decompress).CopyTo(stream3);
                    stream3.Position = 0L;
                    decoded3 = reader3.ReadToEnd();
                    reader3.Close();
                }

                stream3.Close();
            }

            stream2.Close();
        }

        string assertion = System.IO.File.ReadAllText(Server.MapPath("~/assertion.xml"));

        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";

        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

        XmlDocument assertionDoc = new XmlDocument();
        assertionDoc.LoadXml(assertion);

        XmlDocument response = new XmlDocument();
        response.LoadXml(decoded3);

        SignedXml signedXml = new SignedXml(assertionDoc);

        Reference reference = new Reference();

        signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
        signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;

        reference.Uri = "#_79723ebe12aed3704c4d8de6ea16cf90c0d7451da0";

        reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
        reference.AddTransform(new XmlDsigExcC14NTransform());
        reference.DigestMethod = SignedXml.XmlDsigSHA1Url;
        reference.DigestValue = Encoding.ASCII.GetBytes("3jdMJaumbeC3UJ16d8VQJWjKQKU=");

        signedXml.AddReference(reference);

        signedXml.SigningKey = rsaKey;

        HMACSHA256 key = new HMACSHA256();

        signedXml.ComputeSignature(key);

        XmlElement xmlDigitalSignature = signedXml.GetXml();

        assertionDoc.GetElementsByTagName("ds:SignatureValue")[0].InnerText = xmlDigitalSignature.InnerText;

        model.Base64EncodedAssertion = Convert.ToBase64String(Encoding.ASCII.GetBytes(assertionDoc.InnerXml));

        model.Message += "Success";
    }
    catch (Exception ex)
    {
        model.Message = ex.Message;
    }

    return View(model);

}

我正在加载一个在SSO 2.0文档文件中提供的断言文件

<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="9f84acebb80533147969eac6a0aead9603c807b5b" Version="2.0" IssueInstant="2015-07-08T09:44:20Z" Destination="https://testdata.redpoints.co.uk/saml/consume" InResponseTo="_e4098d80-0783-0133-f409-7cd1c3f7b75b">
  <saml:Issuer>https://openidp.feide.no</saml: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:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <ds:Reference URI="#_b9f84acebb80533147969eac6a0aead9603c807b5b">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
          <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <ds:DigestValue>3jdMJaumbeC3UJ16d8VQJWjKQKU=</ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>dewQ7U/QjQtaeUHHk/wgzyCLXi0B6mnmMNCUJgj+taxa/c+HsrKVx97iMbMaoFWRd9Ps9SjNr5P40yC2I5j3Dx9pheBAgKX6RRAl0C7CJM36XZAqWwA1CBlDCqx1H3vTeSeotuOovzKVhnpQj9AL38GmFYqHnNS1e5pCfugI72o=</ds:SignatureValue>
    <ds:KeyInfo>
      <ds:X509Data>
        <ds:X509Certificate>MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==</ds:X509Certificate>
      </ds:X509Data>
    </ds:KeyInfo>
  </ds:Signature>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
  </samlp:Status>
  <saml:Assertion xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="_79723ebe12aed3704c4d8de6ea16cf90c0d7451da0" Version="2.0" IssueInstant="2015-07-08T09:44:20Z">
    <saml:Issuer>https://openidp.feide.no</saml: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:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <ds:Reference URI="#_79723ebe12aed3704c4d8de6ea16cf90c0d7451da0">
          <ds:Transforms>
            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          </ds:Transforms>
          <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <ds:DigestValue>sDFB4zP6PHBacygh64DRtaeowZ8=</ds:DigestValue>
        </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>GY1M5iO5yht1JLOAOmFBUdZPtxKZeek5jG77w7Ct6A+H1qbUAbX7u8PmniGdOXkllxPWqB+L4Gtd39WbCEoWiQ9QvY/pVz2xe6xzI9gVsnJBP0alalyCZglnxNpQ2x+692OcpVXnbau4LJoFv2+0zktXPhQEI3CfAyixOpASu1w=</ds:SignatureValue>
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </ds:Signature>
    <saml:Subject>
      <saml:NameID SPNameQualifier="https://testdata.redpoints.co.uk/saml/metadata" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_36355e0a362adec0f5753911aff3b14f9b21d9c2b8</saml:NameID>
      <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <saml:SubjectConfirmationData NotOnOrAfter="2017-11-08T09:49:20Z" Recipient="https://testdata.redpoints.co.uk/saml/consume" InResponseTo="_e4098d80-0783-0133-f409-7cd1c3f7b75b" />
      </saml:SubjectConfirmation>
    </saml:Subject>
    <saml:Conditions NotBefore="2015-07-08T09:43:50Z" NotOnOrAfter="2017-11-08T09:49:20Z">
      <saml:AudienceRestriction>
        <saml:Audience>https://testdata.redpoints.co.uk/saml/metadata</saml:Audience>
      </saml:AudienceRestriction>
    </saml:Conditions>
    <saml:AuthnStatement AuthnInstant="2015-07-08T09:15:58Z" SessionNotOnOrAfter="2017-11-08T17:44:20Z" SessionIndex="_066bce0e07565d6a61ae7e94fe95d8bcdd79a3cfd0">
      <saml:AuthnContext>
        <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
      </saml:AuthnContext>
    </saml:AuthnStatement>
    <saml:AttributeStatement>
      <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
        <saml:AttributeValue xsi:type="xs:string">102112</saml:AttributeValue>
      </saml:Attribute>
    </saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>

我已经尝试了许多不同的方法来完成这项工作,下载了多个.net库,这些库旨在帮助为iDP设置SSO但没有运气。

2 个答案:

答案 0 :(得分:1)

我的回复可能对您没有帮助,但至少它给您的想法很少。

SAML中有2个流程:

  1. Sp-Initiated [Service Provider Initiated]:服务提供商通过向Idp发送SSO SAML请求来启动流程。 Idp服务器处理请求并确保用户经过身份验证并被授权使用此服务,然后Idp向服务提供商(SP)发送SSO SAML响应包含断言(有关经过身份验证的用户的数据)。 enter image description here

  2. Idp-Initiated [身份提供商已启动]:Idp对用户进行身份验证和授权,并向服务提供商发送SSO SAML请求(仅限Sp-Initiated的第二部分)。

    idp-initiated

  3. 在等待SAML请求时。这意味着您的流程是SP启动的。 首先,您需要生成元数据并将其发送到红点。此元数据至少应包括您的entityId和SSO端点以及用于签名/加密的X.509证书。 您可以使用onlogin website to generate your metadata

    如果你已经这样做了。我建议你使用https://www.componentspace.com/库。它快速,高效且维护良好。不幸的是,这是付费但有一个试用期,所以你可以测试它。

    查看有关此link

    的图书馆文档

    如果您使用此库,您需要做的就是添加saml.config文件,如下所示

    <?xml version="1.0"?>
    <SAMLConfiguration xmlns="urn:componentspace:SAML:2.0:configuration">
      <IdentityProvider Name="YourEntityId"
                        Description="Description"
                        LocalCertificateFile="Your certificate private key *.pfx"
                        LocalCertificatePassword="Your certificate password"/>
    
      <PartnerServiceProviders>
        <PartnerServiceProvider Name="https://testdata.redpoints.co.uk/saml/metadata"
                                Description="Red Point Service Provider"
                                <!-- those options should be based on redpoint metadata WantAuthnRequestSigned="true"
                                SignSAMLResponse="false"
                                SignAssertion="true"
                                EncryptAssertion="false"-->
                                AssertionConsumerServiceUrl="https://testdata.redpoints.co.uk/saml/consume"
                                PartnerCertificateFile="Path to redpoint certificate file .cer"/>
    
      </PartnerServiceProviders>
    
    
    
    </SAMLConfiguration>
    

    并在您的操作方法中添加以下内容:

     SAMLConfigurationFile.Load();
     string partnerSP = null;
                    SSOOptions options = null;
                    SAMLIdentityProvider.ReceiveSSO(Request, out partnerSP, out options);
           string userName = "robert@test.com";
     IDictionary<string, string> attributes = new Dictionary<string, string>();
      attributes.Add("NameID", "robert@test.com"); // as an example for possible attribute
    
        SAMLIdentityProvider.SendSSO(Response, userName, attributes);
    

    我建议您还安装浏览器扩展程序以检测SAML请求/响应。这将帮助您查看要发送的输出。

    我希望我的回复会给你一些帮助。

答案 1 :(得分:0)

有许多SAML堆栈 - SAML : SAML connectivity / toolkit

我肯定会建议你不要自己动手。你解决这个问题只是为了遇到下一个问题。

大多数堆栈的问题在于它们是客户端。你想要服务器端。

同意组件空间建议 - 它可以做到双方。

或此one - 目前处于测试阶段。

或者看一下OpenSAML源代码 - 它的Java,但其原理是相同的。