0
我能夠使用OpenSAML創建SAMLResponse,但作爲理智檢查,我希望驗證簽名。收件人要斷言要簽名,但沒有響應,這看起來只有精細:使用OpenSAML創建並簽名響應(使用Java)但在驗證簽名時遇到問題
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:Response ID="1111111111" Version="2.0"
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2:Assertion Version="2.0"
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
<ds:Reference URI="" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:Transforms xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
<ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">H1M/MSp4KUwKryB9c99XvE6PWaU=
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
npeqj35bPh06G6WcSBzfpaDEqVUzhEOgqARKB6NIowGcAoD6yHpmDYTJ0nXvS31cRFYxqWtCVIrX
e7abo3mpwfLI7FjpEawP+8IEaMi++b0hN1Xri/bprMNjxB7kldDGJc2WkbdVRAAIknQetxytd9gB
WGhP97zLyGPVK23orH/JF09bFgoqGPgd/14fuY5ksOJuFfuZD4rsCOxxicYrfMsJDnlUfz8n18Xw
Jj6vX/0SDoDknMz9h4kh1TU4tus0FvIAPYLNB7QV7Iarpd+5Q9R8mj+NJEviFH/DZlqE/NYrxRNt
iinOgOnz1x3dtnDr2O/BHIW55mlBFi0L6wJ7ow==
</ds:SignatureValue>
</ds:Signature>
</saml2:Assertion>
</saml2p:Response>
如果我驗證簽名前編組的響應,它是有效的:
protected static void testSignature(Credential credential) throws Exception {
DefaultBootstrap.bootstrap();
SignatureBuilder builder = new SignatureBuilder();
Signature signature = builder.buildObject();
signature.setSigningCredential(credential);
signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);
signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
Assertion assertion = new AssertionBuilder().buildObject();
assertion.setVersion(SAMLVersion.VERSION_20);
assertion.setSignature(signature);
AssertionMarshaller aMarsh = new AssertionMarshaller();
aMarsh.marshall(assertion);
Signer.signObject(signature);
Response response = new ResponseBuilder().buildObject();
response.setVersion(SAMLVersion.VERSION_20);
response.setID("1111111111");
response.getAssertions().add(assertion);
Signature sig = response.getAssertions().get(0).getSignature();
SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
profileValidator.validate(sig);
SignatureValidator sigValidator = new SignatureValidator(credential);
sigValidator.validate(sig); //valid
}
但是如果我通過添加以下代碼來反應,即使我在編組之前設置了簽名,它也會返回無效:
...
Signature sig = response.getAssertions().get(0).getSignature();
ResponseMarshaller rMarsh = new ResponseMarshaller();
Element plain = rMarsh.marshall(response);
SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
profileValidator.validate(sig);
SignatureValidator sigValidator = new SignatureValidator(credential);
sigValidator.validate(sig); //invalid
最後,我試圖unmarshall編組響應,然後讀取和驗證簽名,即使我可以驗證響應是否與編組/解組之前相同,仍然無效。
...
ResponseMarshaller rMarsh = new ResponseMarshaller();
Element plain = rMarsh.marshall(response);
String samlResponse1 = XMLHelper.nodeToString(plain);
UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(plain);
XMLObject responseXmlObj = unmarshaller.unmarshall(plain);
Response newResponse = (Response) responseXmlObj;
plain = rMarsh.marshall(newResponse);
String samlResponse2 = XMLHelper.nodeToString(plain);
System.out.println(StringUtils.equals(samlResponse1, samlResponse2)); //true
Signature sig = newResponse.getAssertions().get(0).getSignature();
SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
profileValidator.validate(sig);
SignatureValidator sigValidator = new SignatureValidator(credential);
sigValidator.validate(sig); //invalid
這是怎麼回事?有什麼我在這裏失蹤?
最初的SAMLResponse是否有換行符?如果是,那麼換行符是什麼?對我而言,大部分時間都是因爲換行符在處理步驟之間沒有保持原樣,在這種情況下是編組。 – Thuan