如何获取Adfs Saml响应数据

时间:2018-01-08 10:40:57

标签: asp.net-mvc adfs adfs2.0 adfs3.0

目前我正在使用ADFS登录。我正在从Adfs服务器获得响应。但是我无法从响应中获取任何信息Saml。我该如何获取信息是否正确?

<br /><br />
  <samlp:Response Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
    Destination="https://demo.apps.com/adfsauthlogin/login"
    ID="_cbb5174b-36b4-4e75-9d8a-7f2d47ccb9bc" IssueInstant="2018-01-08T06:09:16.122Z" Version="2.0"
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
    <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://adfs.Sample.com/adfs/services/trust</Issuer>
    <samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>
    <EncryptedAssertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
        <xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
            xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
            <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                <e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
                    <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/></e:EncryptionMethod>
                    <KeyInfo>
                        <ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                            <ds:X509IssuerSerial>
                                <ds:X509IssuerName>CN=ADFS Encryption - demo.apps.com</ds:X509IssuerName>
                                <ds:X509SerialNumber>33157209971584938906555805034885884694</ds:X509SerialNumber>
                            </ds:X509IssuerSerial>
                        </ds:X509Data>
                    </KeyInfo>
                    <e:CipherData>
                        <e:CipherValue> ==- Value -== </e:CipherValue>
                    </e:CipherData>
                </e:EncryptedKey>
            </KeyInfo>
            <xenc:CipherData>
                <xenc:CipherValue> ==- Value -== </xenc:CipherValue>
            </xenc:CipherData>
        </xenc:EncryptedData>
    </EncryptedAssertion>
</samlp:Response>

1 个答案:

答案 0 :(得分:0)

今天我遇到了同样的问题,我从这个帖子找到了我的问题的解决方案How to Decrypt EncryptedAssertion using System.Cryptography

我对此进行了一些调整,以便为ADFS SAMLResponse工作。 这是我的解决方案......

private void DecryptSamlAssertion(XmlDocument xmlDocument, X509Certificate2 cert)
    {
        EncryptedXmlWithPreconfiguredAsymmetricKey encXml = new EncryptedXmlWithPreconfiguredAsymmetricKey(xmlDocument, cert);
        if (xmlDocument.GetElementsByTagName("EncryptedAssertion").Count > 0)
        {
            var encryptedAssertion = xmlDocument.GetElementsByTagName("EncryptedAssertion")[0];
            xmlDocument.DocumentElement.ReplaceChild(encryptedAssertion.FirstChild, encryptedAssertion);
            while (xmlDocument.GetElementsByTagName("xenc:EncryptedData").Count > 0)
            {
                XmlElement encryptedDataElement = xmlDocument.GetElementsByTagName("xenc:EncryptedData")[0] as XmlElement;
                EncryptedData encryptedData = new EncryptedData();
                encryptedData.LoadXml(encryptedDataElement);

                SymmetricAlgorithm symmKey = encXml.GetDecryptionKey(encryptedData, encryptedData.EncryptionMethod.KeyAlgorithm);
                symmKey.IV = encXml.GetDecryptionIV(encryptedData, encryptedData.EncryptionMethod.KeyAlgorithm);
                symmKey.Padding = encXml.Padding;
                symmKey.Mode = encXml.Mode;

                byte[] decryptedData = encXml.DecryptData(encryptedData, symmKey);
                encXml.ReplaceData(encryptedDataElement, decryptedData);
            }
        }
    }

public class EncryptedXmlWithPreconfiguredAsymmetricKey : EncryptedXml
{
    public readonly X509Certificate2 _encryptionCert;
    public EncryptedXmlWithPreconfiguredAsymmetricKey(XmlDocument xmlDoc, X509Certificate2 encryptionCert) : base(xmlDoc)
    {
        _encryptionCert = encryptionCert;
    }

    public override SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri)
    {
        if (encryptedData == null)
            throw new ArgumentNullException("encryptedData");

        if (encryptedData.KeyInfo == null)
            return null;
        IEnumerator keyInfoEnum = encryptedData.KeyInfo.GetEnumerator();
        KeyInfoRetrievalMethod kiRetrievalMethod;
        KeyInfoName kiName;
        KeyInfoEncryptedKey kiEncKey;
        EncryptedKey ek = null;

        while (keyInfoEnum.MoveNext())
        {
            kiName = keyInfoEnum.Current as KeyInfoName;

            kiRetrievalMethod = keyInfoEnum.Current as KeyInfoRetrievalMethod;

            kiEncKey = keyInfoEnum.Current as KeyInfoEncryptedKey;
            if (kiEncKey != null)
            {
                ek = kiEncKey.EncryptedKey;
                break;
            }
        }

        // if we have an EncryptedKey, decrypt to get the symmetric key
        if (ek != null)
        {
            // now process the EncryptedKey, loop recursively
            // If the Uri is not provided by the application, try to get it from the EncryptionMethod 
            if (symmetricAlgorithmUri == null)
            {
                if (encryptedData.EncryptionMethod == null)
                    throw new CryptographicException("Cryptography_Xml_MissingAlgorithm");
                symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm;
            }
            byte[] key = ek.CipherData.CipherValue;
            if (key == null)
                throw new CryptographicException("Cryptography_Xml_MissingDecryptionKey");

            // Ignore any information about the asymmetric key in the XML, and just use our predefined certificate
            var rsaKey = (RSA)_encryptionCert.PrivateKey;

            byte[] symkey = DecryptKey(key, rsaKey, true);

            SymmetricAlgorithm symAlg = (SymmetricAlgorithm)CryptoConfig.CreateFromName(symmetricAlgorithmUri);
            symAlg.Key = symkey;
            return symAlg;
        }
        return null;
    }
}