SAML摘要验证失败

时间:2016-04-27 18:41:31

标签: php ssl saml verification digest

我有一个PHP脚本,在SAML身份验证过程中充当IdP。 PHP脚本生成SAML响应,该响应发送给我们的供应商(service.com)。但是,我一直收到“ID6018:摘要验证失败以供参考”错误消息。

对于证书,我使用的是通过openssl生成的2048位自签名RSA证书。供应商在其SP上加载了相同的证书及其公钥。

这是生成并签署SAML响应的PHP代码:

$response_params = array();
$time = time();
$response_params['IssueInstant'] = samlGetDateTime(time());
$response_params['NotOnOrAfter'] = $notOnOrAfter;
$response_params['NotBefore'] = $notBefore;
$response_params['AuthnInstant'] = samlGetDateTime(time());
$response_params['SessionNotOnOrAfter'] = samlGetDateTime(time());

$response_params['ID'] = samlCreateId();
$response_params['assertID'] = samlCreateId();

$response_params['issuer'] = $issuer;
$response_params['email'] = $authenticatedUser;
$response_params['x509'] = <<<X509
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
X509;

$private_key = <<<RSA_PRIVATE_KEY
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
RSA_PRIVATE_KEY;

$xml = new DOMDocument('1.0','utf-8');

$resp = $xml->createElementNS('urn:oasis:names:tc:SAML:2.0:protocol', 'samlp:Response');

$resp->setAttribute('xmlns:saml', 'urn:oasis:names:tc:SAML:2.0:assertion');
$resp->setAttribute('ID',$response_params['ID']);
$resp->setAttribute('Version','2.0');
$resp->setAttribute('IssueInstant',$response_params['IssueInstant']);
$resp->setAttribute('Destination',$destination);
$resp->setAttribute('InResponseTo',$requestID);
$xml->appendChild($resp);

$issuer = $xml->createElementNS('urn:oasis:names:tc:SAML:2.0:assertion','samlp:Issuer',$response_params['issuer']);
$resp->appendChild($issuer);

$status = $xml->createElementNS('urn:oasis:names:tc:SAML:2.0:protocol','samlp:Status');
$resp->appendChild($status);

$statusCode = $xml->createElementNS('urn:oasis:names:tc:SAML:2.0:protocol','samlp:StatusCode');
$statusCode->setAttribute('Value', 'urn:oasis:names:tc:SAML:2.0:status:Success');
$status->appendChild($statusCode);

$assertion = $xml->createElementNS('urn:oasis:names:tc:SAML:2.0:assertion','saml:Assertion');
$assertion->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:saml', 'urn:oasis:names:tc:SAML:2.0:assertion');
$assertion->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$assertion->setAttribute('xmlns:xs', 'http://www.w3.org/2001/XMLSchema');
$assertion->setAttribute('ID',$response_params['assertID']);
$assertion->setAttribute('Version','2.0');
$assertion->setAttribute('IssueInstant',$response_params['IssueInstant']);
$resp->appendChild($assertion);

$assertion->appendChild($xml->createElement('saml:Issuer',$response_params['issuer']));

$subject = $xml->createElement('saml:Subject');
$assertion->appendChild($subject);

$nameid = $xml->createElement('saml:NameID',$response_params['email']);

$nameid->setAttribute('Format','urn:oasis:names:tc:SAML:2.0:nameid-format:email');
$nameid->setAttribute('SPNameQualifier','https://service.com/adfs/ls/');
$subject->appendChild($nameid);

$confirmation = $xml->createElement('saml:SubjectConfirmation');
$confirmation->setAttribute('Method','urn:oasis:names:tc:SAML:2.0:cm:bearer');
$subject->appendChild($confirmation);

$confirmationdata = $xml->createElement('saml:SubjectConfirmationData');
$confirmationdata->setAttribute('InResponseTo',$requestID);
$confirmationdata->setAttribute('NotOnOrAfter',$response_params['NotOnOrAfter']);
$confirmationdata->setAttribute('Recipient',$destination);
$confirmation->appendChild($confirmationdata);

$condition = $xml->createElement('saml:Conditions');
$condition->setAttribute('NotBefore',$response_params['NotBefore']);
$condition->setAttribute('NotOnOrAfter',$response_params['NotOnOrAfter']);
$assertion->appendChild($condition);

$audiencer = $xml->createElement('saml:AudienceRestriction');
$condition->appendChild($audiencer);

$audience = $xml->createElement('saml:Audience','http://service.com/adfs/services/trust');
$audiencer->appendChild($audience);

$authnstat = $xml->createElement('saml:AuthnStatement');
$authnstat->setAttribute('AuthnInstant',$response_params['AuthnInstant']);
$authnstat->setAttribute('SessionIndex','_'.samlCreateId());//$response_params['assertID']
$authnstat->setAttribute('SessionNotOnOrAfter',$response_params['SessionNotOnOrAfter']);
$assertion->appendChild($authnstat);

$authncontext = $xml->createElement('saml:AuthnContext');
$authnstat->appendChild($authncontext);

$authncontext_ref = $xml->createElement('saml:AuthnContextClassRef','urn:oasis:names:tc:SAML:2.0:ac:classes:Password');
$authncontext->appendChild($authncontext_ref);

$attrStatement = $xml->createElement('saml:AttributeStatement');
$attr = $xml->createElement('saml:Attribute');
$attr->setAttribute('Name', 'mail');
$attr->setAttribute('NameFormat', 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic');
$attrValue = $xml->createElement('saml:AttributeValue', $response_params['email']);
$attrValue->setAttribute('xsi:type', 'xs:string');
$attr->appendChild($attrValue);
$attrStatement->appendChild($attr);

$attr = $xml->createElement('saml:Attribute');
$attr->setAttribute('Name', 'preferredLanguage');
$attr->setAttribute('NameFormat', 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic');
$attrValue = $xml->createElement('saml:AttributeValue', 'en');
$attrValue->setAttribute('xsi:type', 'xs:string');
$attr->appendChild($attrValue);
$attrStatement->appendChild($attr);
$assertion->appendChild($attrStatement);

//Private KEY
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
$objKey->loadKey($private_key);

//Sign the Assertion
$objXMLSecDSig = new XMLSecurityDSig();
$objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
$objXMLSecDSig->addReferenceList(array($assertion), XMLSecurityDSig::SHA1,
array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),array('id_name'=>'ID')); 
$objXMLSecDSig->sign($objKey);
$objXMLSecDSig->add509Cert($response_params['x509']);

$objXMLSecDSig->insertSignature($assertion,$subject);

$r = $xml->saveXML();

return $r;

这是创建的SAML响应:

<?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="hlboelmomjlpigfakcaaenjnkfdeldibobmfddaa" Version="2.0" IssueInstant="2016-04-27T18:20:17Z" Destination="https://service.com/adfs/ls/" InResponseTo="id-694bef3c-da75-402a-9275-0f6170ace280">
    <samlp:Issuer xmlns:samlp="urn:oasis:names:tc:SAML:2.0:assertion">PHP_URL</samlp:Issuer>
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="pfx3116ddd8-61a9-5c07-70ba-abc1781ebc0d" Version="2.0" IssueInstant="2016-04-27T18:20:17Z">
        <saml:Issuer>PHP_URL</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="#pfx3116ddd8-61a9-5c07-70ba-abc1781ebc0d">
                    <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>m89OYak6/qfoES3ncu1bgXkef9Q=</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>PXkGpH8aKgGf+iQpqN57OJvtS3+m0EsHcY+J8H6mC8S/KfHQzwtHXsLK4Pz6ykH0HTX0gsM3js24NqOciylrSvuBEo8QjA8Jk5prNnU5Xbv5u0oyjCQmx5eeBhwgsJ4DolTuM2kHskYcUtcDEdcQLmj6CsgfWmn3D4tf1t6T0LzZVFy3RnAcdUFhC/BAHI1a20ddTjoygJYCuxh8MdwQ6uAmpIGKSVHrRB1FJas4mz277+jz2JleUq8fYGfjZNVrAkWX7+OW+vFwEfW+FcthHU0kslifnLEeY749O4oOPBsOD+f+vB7dfOXztztCB/SAeTVhntb5AktbLBBnvxHiXQ==</ds:SignatureValue>
            <ds:KeyInfo>
                <ds:X509Data>
                    <ds:X509Certificate>CERTIFICATE</ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </ds:Signature>
        <saml:Subject>
            <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:email" SPNameQualifier="https://service.com/adfs/ls/">myemail@domain.com</saml:NameID>
            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <saml:SubjectConfirmationData InResponseTo="id-694bef3c-da75-402a-9275-0f6170ace280" NotOnOrAfter="2016-04-27T18:30:17Z" Recipient="https://service.com/adfs/ls/"/>
            </saml:SubjectConfirmation>
        </saml:Subject>
        <saml:Conditions NotBefore="2016-04-27T18:10:17Z" NotOnOrAfter="2016-04-27T18:30:17Z">
            <saml:AudienceRestriction>
                <saml:Audience>http://service.com/adfs/services/trust</saml:Audience>
            </saml:AudienceRestriction>
        </saml:Conditions>
        <saml:AuthnStatement AuthnInstant="2016-04-27T18:20:17Z" SessionIndex="_blfhnlolcoogjokbahplfacoehddoglankhaedgg" SessionNotOnOrAfter="2016-04-27T18:20:17Z">
            <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="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xsi:type="xs:string">myemail@domain.com</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="preferredLanguage" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xsi:type="xs:string">en</saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
    </saml:Assertion>
</samlp:Response>

非常感谢任何帮助!

0 个答案:

没有答案