2011-09-29 7 views
21

मैं एक जेएक्स-डब्ल्यूएस वेब सेवा लिखना चाहता हूं जो http://www.w3.org/TR/xmldsig-core/ अनुशंसा का उपयोग करके मेरे एसओएपी संदेशों पर हस्ताक्षर करता है।साइन जेएक्स-डब्ल्यूएस एसओएपी अनुरोध

मैं इंटरनेट पर क्या मिला के साथ मैं एक JAX-WS हैंडलर (SOAPHandler<SOAPMessageContext>) सोप अनुरोध की एक प्रति को बदलने के लिए प्रबंधन करता है कि लिखा है:

@Override 
public boolean handleMessage(SOAPMessageContext smc) { 
    Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 
    SOAPMessage message = smc.getMessage(); 

    if (outboundProperty) { 
     try { 
      SOAPPart soapPart = message.getSOAPPart(); 
      SOAPEnvelope soapEnvelope = soapPart.getEnvelope(); 

      Source source = soapPart.getContent(); 

      Node root = null; 
      Document doc22 = null; 
      if (source instanceof DOMSource) { 
       root = ((DOMSource) source).getNode(); 
      } else if (source instanceof SAXSource) { 
       InputSource inSource = ((SAXSource) source).getInputSource(); 
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
       dbf.setNamespaceAware(true); 
       DocumentBuilder db = null; 

       db = dbf.newDocumentBuilder(); 

       doc22 = db.parse(inSource); 
       root = (Node) doc22.getDocumentElement(); 
      } 

      XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); 

      Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null), 
        Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), 
        null, null); 

      SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, 
        (C14NMethodParameterSpec) null), 
        fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), 
        Collections.singletonList(ref)); 

      // Load the KeyStore and get the signing key and certificate. 
      KeyStore ks = KeyStore.getInstance("JKS"); 
      ks.load(new FileInputStream("client_keystore.jks"), "changeit".toCharArray()); 
      KeyStore.PrivateKeyEntry keyEntry = 
        (KeyStore.PrivateKeyEntry) ks.getEntry("client", new KeyStore.PasswordProtection("changeit".toCharArray())); 
      X509Certificate cert = (X509Certificate) keyEntry.getCertificate(); 
      // Create the KeyInfo containing the X509Data. 
      KeyInfoFactory kif2 = fac.getKeyInfoFactory(); 
      List x509Content = new ArrayList(); 
      x509Content.add(cert.getSubjectX500Principal().getName()); 
      x509Content.add(cert); 
      X509Data xd = kif2.newX509Data(x509Content); 
      KeyInfo ki = kif2.newKeyInfo(Collections.singletonList(xd)); 

      Element header = getFirstChildElement(root/*.getDocumentElement()*/); 
      DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), header /*doc.getDocumentElement()*/); 

      XMLSignature signature = fac.newXMLSignature(si, ki); 

      signature.sign(dsc); 

      //TODO: change this to update the SOAP message, not write it to disks 
      OutputStream os = new FileOutputStream("out.xml"); 
      TransformerFactory tf = TransformerFactory.newInstance(); 
      Transformer trans = tf.newTransformer(); 
      trans.transform(new DOMSource(root), new StreamResult(os)); 

     } catch (Exception ex) { 
      System.out.println(ex); 
     } 
    } 

    return true; 
} 

लेकिन मैं समझ नहीं अद्यतन करने के लिए कैसे एसओएपी अनुरोध?

+0

क्या साबुनपार्ट.सेट सामग्री (नया डोमसोर्स (रूट)) काम नहीं करता है? मैं बस अनुमान लगा रहा हूं, मैंने इसे स्वयं नहीं किया है। –

+0

दुर्भाग्यवश, यह बोड और हेडर तत्व खाली करता है। हालांकि, देखने के लिए धन्यवाद! – AndrewBourgeois

+0

क्या आपको अभी तक इस समस्या का समाधान मिला है? मैं उत्सुक हूं क्योंकि मैं कुछ ऐसा करने जा रहा हूं –

उत्तर

6

एप्लिकेशन सर्वर में एकीकृत कार्यक्षमता का उपयोग करने का सबसे आसान तरीका है। उदाहरण के लिए: Securing JAX-WS Web services using message-level security with WebSphere App Server

WAS पर हस्ताक्षर कॉन्फ़िगर कैसे करें आप here पा सकते हैं।

और यहां WebLogic documentation about Configuring Message-Level Security है।

+0

यह सामान्य सुरक्षित नहीं है, जो अच्छी तरह से समझ में आता है, पर हस्ताक्षर करने के बारे में है। शायद आप एक और विस्तृत लिंक और/या उदाहरण प्रदान कर सकते हैं? –

+0

@ लुकासएडर: संदेश-स्तर सुरक्षा भी हस्ताक्षर करने का संदर्भ देती है। इस पृष्ठ पर आप कॉन्फ़िगरेशन पर हस्ताक्षर करने के लिए लिंक भी पा सकते हैं। मैंने इसे अब प्रतिक्रिया में जोड़ा। – zacheusz

+1

बहुत अच्छा। विशेष रूप से दूसरा लिंक! बहुत बहुत धन्यवाद –

6

मैं साबुन अनुरोध के एक्सएमएल डिजिटल हस्ताक्षर के लिए एक SOAPHandler विकसित करता हूं।

public class SOAPSecurityHandler implements 
     LogicalHandler<LogicalMessageContext> { 

    static final String KEYSTORE_FILE = "keystore_name.jks"; 
    static final String KEYSTORE_INSTANCE = "JKS"; 
    static final String KEYSTORE_PWD = "123456"; 
    static final String KEYSTORE_ALIAS = "keystore"; 

    public Set<QName> getHeaders() { 
     return Collections.emptySet(); 
    } 

    @Override 
    public boolean handleMessage(LogicalMessageContext smc) { 
     Boolean outboundProperty = (Boolean) smc 
       .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 

     try { 

      if (outboundProperty) { 

       Source source = smc.getMessage().getPayload(); 

       Node root = null; 

       root = ((DOMSource) source).getNode(); 

       XMLSignatureFactory fac = XMLSignatureFactory 
         .getInstance("DOM"); 

       Reference ref = fac.newReference("", fac.newDigestMethod(
         DigestMethod.SHA1, null), Collections.singletonList(fac 
         .newTransform(Transform.ENVELOPED, 
           (TransformParameterSpec) null)), null, null); 

       SignedInfo si = fac.newSignedInfo(fac 
         .newCanonicalizationMethod(
           CanonicalizationMethod.INCLUSIVE, 
           (C14NMethodParameterSpec) null), fac 
         .newSignatureMethod(SignatureMethod.RSA_SHA1, null), 
         Collections.singletonList(ref)); 

       // Load the KeyStore and get the signing key and certificate. 
       KeyStore ks = KeyStore.getInstance(KEYSTORE_INSTANCE); 
       ks.load(new FileInputStream(KEYSTORE_FILE), 
         KEYSTORE_PWD.toCharArray()); 
       KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks 
         .getEntry(
           KEYSTORE_ALIAS, 
           new KeyStore.PasswordProtection(KEYSTORE_PWD 
             .toCharArray())); 
       X509Certificate cert = (X509Certificate) keyEntry 
         .getCertificate(); 
       // Create the KeyInfo containing the X509Data. 
       KeyInfoFactory kif2 = fac.getKeyInfoFactory(); 
       List x509Content = new ArrayList(); 
       x509Content.add(cert.getSubjectX500Principal().getName()); 
       x509Content.add(cert); 
       X509Data xd = kif2.newX509Data(x509Content); 
       KeyInfo ki = kif2.newKeyInfo(Collections.singletonList(xd)); 

       Element header = DOMUtils.getFirstChildElement(root); 
       DOMSignContext dsc = new DOMSignContext(
         keyEntry.getPrivateKey(), header); 

       XMLSignature signature = fac.newXMLSignature(si, ki); 

       signature.sign(dsc); 

      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return true; 

    } 

    public boolean handleFault(SOAPMessageContext smc) { 
     // addDigitalSignature(smc); 
     return true; 
    } 

    // nothing to clean up 
    public void close(MessageContext messageContext) { 
    } 

    @Override 
    public boolean handleFault(LogicalMessageContext arg0) { 
     // TODO Auto-generated method stub 
     return false; 
    } 

} 

मुझे लगता है कि @AndrewBourgeois के कोड में समस्या स्रोत प्राप्त करने का तरीका है।

सादर,

+0

DomUtils के लिए तर्क कहां है? – lordoku

1

आप soapPart.saveChanges कोशिश कर सकते हैं();

0

कोड लाइन के बाद:

signature.sign(dsc); 

डालने इस बयान:

soapMsg.saveChanges(); 

यह अपने परिवर्तनों को सहेजने होगा।

संबंधित मुद्दे