2016-10-05 31 views
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 

這是怎麼回事?有什麼我在這裏失蹤?

+0

最初的SAMLResponse是否有換行符?如果是,那麼換行符是什麼?對我而言,大部分時間都是因爲換行符在處理步驟之間沒有保持原樣,在這種情況下是編組。 – Thuan

回答

0

解決了這個問題。斷言需要一個與Response ID不同的ID值。我只需要添加下面的代碼行,它的工作。

assertion.setID("1111111112");