2014-10-19 59 views
2

我有一个使用WS-Security实现的外部SOAP Web服务和SAML ... Web服务的SOAP请求是以下内容: -如何使用Java生成SAML安全的SOAP请求并使用SAAJ调用永久的webservice

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://services.test.getDesignation.com/schema/MainData/V1"> 
    <soapenv:Header> 
     <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
     <saml1:Assertion AssertionID="_1EB4A2A52467EB9373141364603919871" IssueInstant="2014-10-18T15:27:19.198Z" Issuer="self" MajorVersion="1" MinorVersion="1" xsi:type="saml1:AssertionType" xmlns:saml1="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
      <saml1:Conditions NotBefore="2014-10-18T15:27:19.198Z" NotOnOrAfter="2014-10-18T15:32:19.198Z"/> 
      <saml1:AuthenticationStatement AuthenticationInstant="2014-10-18T15:27:19.198Z" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password" xsi:type="saml1:AuthenticationStatementType"> 
       <saml1:Subject> 
        <saml1:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">getDesignationservice</saml1:NameIdentifier> 
        <saml1:SubjectConfirmation> 
        <saml1:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:sender-vouches</saml1:ConfirmationMethod> 
        </saml1:SubjectConfirmation> 
       </saml1:Subject> 
      </saml1:AuthenticationStatement> 
     </saml1:Assertion> 
     <wsse:UsernameToken wsu:Id="UsernameToken-1EB4A2A52467EB9373141364603919870"> 
      <wsse:Username>username</wsse:Username> 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password> 
      <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">FCyqP2DThmR6ygNWnzNrKQ==</wsse:Nonce> 
      <wsu:Created>2014-10-18T15:27:19.198Z</wsu:Created> 
     </wsse:UsernameToken> 
     <wsu:Timestamp wsu:Id="TS-1EB4A2A52467EB9373141364603919869"> 
      <wsu:Created>2014-10-18T15:27:19.197Z</wsu:Created> 
      <wsu:Expires>2014-10-18T15:28:19.197Z</wsu:Expires> 
     </wsu:Timestamp> 
     </wsse:Security> 
    </soapenv:Header> 
    <soapenv:Body> 
     <v1:getDesignationRequest> 
     <v1:DesignationCode>bd</v1:DesignationCode> 
     </v1:getDesignationRequest> 
    </soapenv:Body> 
</soapenv:Envelope> 

现在,我要做的是用SAAJ调用Java代码的外部服务..

到目前为止,我试过如下: -

import java.io.ByteArrayOutputStream; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.text.DateFormat; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.Iterator; 
import java.util.Random; 
import java.util.TimeZone; 

import javax.xml.namespace.QName; 
import javax.xml.soap.MessageFactory; 
import javax.xml.soap.SOAPBody; 
import javax.xml.soap.SOAPBodyElement; 
import javax.xml.soap.SOAPConnection; 
import javax.xml.soap.SOAPConnectionFactory; 
import javax.xml.soap.SOAPElement; 
import javax.xml.soap.SOAPEnvelope; 
import javax.xml.soap.SOAPException; 
import javax.xml.soap.SOAPHeader; 
import javax.xml.soap.SOAPHeaderElement; 
import javax.xml.soap.SOAPMessage; 
import javax.xml.soap.SOAPPart; 
import javax.xml.transform.Source; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.stream.StreamResult; 

import org.apache.xerces.impl.dv.util.Base64; 
import org.w3c.dom.Node; 


public class SOAPSecurity3 { 

    private static String calculatePasswordDigest(String nonce, String created, String password) { 
     String encoded = null; 
     try { 
      String pass = hexEncode(nonce) + created + password; 
      MessageDigest md = MessageDigest.getInstance("SHA1"); 
      md.update(pass.getBytes()); 
      byte[] encodedPassword = md.digest(); 
      encoded = Base64.encode(encodedPassword); 
     } catch (NoSuchAlgorithmException ex) { 
      /* Logger.getLogger(HeaderHandler.class.getName()).log(Level.SEVERE, null, ex);*/ 
     } 

     return encoded; 
    } 

    private static String hexEncode(String in) { 
     StringBuilder sb = new StringBuilder(""); 
     for (int i = 0; i < (in.length() - 2) + 1; i = i + 2) { 
      int c = Integer.parseInt(in.substring(i, i + 2), 16); 
      char chr = (char) c; 
      sb.append(chr); 
     } 
     return sb.toString(); 
    } 

    private static SOAPMessage createSoapRequest(String value) throws Exception{ 

     //This is used to get time in SOAP request in yyyy-MM-dd'T'HH:mm:ss.SSS'Z' format 
     SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:dd.SSS'Z'"); 
     formatter.setTimeZone(TimeZone.getTimeZone("GMT")); 

     //This is for UsernameToken element 
     Random generator = new Random(); 
     String nonceString = String.valueOf(generator.nextInt(999999999)); // This generate random nonce 
     Date timestamp = new java.util.Date(); 
     String pass = "password"; 
     String user = "username"; 
     //This is for UsernameToken element ends 


     //This is for TimeStamp element value 
     java.util.Date create = new java.util.Date(); 
     java.util.Date expires = new java.util.Date(create.getTime() + (5l * 60l * 1000l)); 
     //This is for TimeStamp value ends 

     MessageFactory messageFactory = MessageFactory.newInstance(); 
     SOAPMessage soapMessage = messageFactory.createMessage(); 
     SOAPPart soapPart = soapMessage.getSOAPPart(); 
     //SOAP Envelope 
     SOAPEnvelope soapEnvelope = soapPart.getEnvelope(); 
     soapEnvelope.addNamespaceDeclaration("v1", "http://services.test.getDesignation.com/schema/MainData/V1"); 

    //SOAP Header    
     SOAPHeader header = soapMessage.getSOAPHeader(); 
     if (header == null) { 
      header = soapEnvelope.addHeader(); 
     } 

     SOAPElement security =header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd").addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); 


       SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse").addAttribute(QName.valueOf("wsu:Id"),"UsernameToken-89293AC6E584F11ADF141358720544137"); 

       // add the username to usernameToken 
       SOAPElement userNameSOAPElement = usernameToken.addChildElement("Username","wsse"); 
       userNameSOAPElement.addTextNode("username"); 

       // add the password to usernameToken 
       SOAPElement passwordSOAPElement = usernameToken.addChildElement("Password","wsse").addAttribute(new QName("Type"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"); 
       passwordSOAPElement.addTextNode("password"); 


       //Adding random Nonce 
       SOAPElement nonce =usernameToken.addChildElement("Nonce", "wsse").addAttribute(new QName("EncodingType"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"); 
       nonce.addTextNode(Base64.encode(hexEncode(nonceString).getBytes())); 

       //Adding created element of UsernameToken 
       SOAPElement created = usernameToken.addChildElement("Created", "wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); 
       created.addTextNode(formatter.format(timestamp)); //formatter formats the date to String 

       //Adding Timestamp 
       SOAPElement timestampElem = security.addChildElement("Timestamp", "wsu").addAttribute(QName.valueOf("wsu:Id"),"TS-1EB4A2A52467EB9373141362942343119"); 
       SOAPElement elem = timestampElem.addChildElement("Created", "wsu"); 
       elem.addTextNode(formatter.format(create)); //formatter formats the date to String 
       timestampElem.addChildElement(elem); 
       elem = timestampElem.addChildElement("Expires", "wsu"); 
       elem.addTextNode(formatter.format(expires)); //formatter formats the date to String 
       timestampElem.addChildElement(elem); 


     //////SOAP Body 
     SOAPBody soapBody = soapEnvelope.getBody(); 
     SOAPElement soapElement = soapBody.addChildElement("getDesignationRequest", "v1"); 
     SOAPElement element1 = soapElement.addChildElement("DesignationCode", "v1"); 
     element1.addTextNode(value); 
     soapMessage.saveChanges(); 
     System.out.println("----------SOAP Request------------"); 
     soapMessage.writeTo(System.out); 
     return soapMessage; 
    } 
    private static void createSoapResponse(SOAPMessage soapResponse) throws Exception { 
     TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
     Transformer transformer = transformerFactory.newTransformer(); 
     Source sourceContent = soapResponse.getSOAPPart().getContent(); 
     System.out.println("\n----------SOAP Response-----------"); 
     ///////////////////////////////////////////////////// 
     StreamResult result = new StreamResult(System.out); 
     transformer.transform(sourceContent, result); 
     System.out.println(); 
    } 
    public static void main(String args[]) throws Exception{ 

      SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); 
      SOAPConnection soapConnection = soapConnectionFactory.createConnection(); 
      String url = "http://localhost:8090/designation"; 
      SOAPMessage soapRequest = createSoapRequest("SSE"); 


      SOAPMessage soapResponse = soapConnection.call(soapRequest, url); 
      createSoapResponse(soapResponse); 

      String Code =soapResponse.getSOAPBody().getElementsByTagName("Code").item(0).getFirstChild().getNodeValue(); 

      if(Code.equals("Success")) 
      { 
      String Result=soapResponse.getSOAPBody().getElementsByTagName("DesignationCodeResult").item(0).getFirstChild().getNodeValue(); 
      System.out.println(Result); 
      } 
      else 
      { 
       System.out.println("SOAP Fault"); 
      } 



      soapConnection.close(); 
     } 
    } 

这是能够产生如下请求和调用外部服务: -

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://services.test.getDesignation.com/schema/MainData/V1"> 
<SOAP-ENV:Header> 
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
<wsse:UsernameToken wsu:Id="UsernameToken-89293AC6E584F11ADF141358720544137"> 
<wsse:Username>username</wsse:Username> 
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password> 
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">FyRZEA==</wsse:Nonce> 
<wsu:Created>2014-10-19T15:38:19.744Z</wsu:Created> 
</wsse:UsernameToken> 
<wsu:Timestamp wsu:Id="TS-1EB4A2A52467EB9373141362942343119"> 
<wsu:Created>2014-10-19T15:38:19.744Z</wsu:Created> 
<wsu:Expires>2014-10-19T15:43:19.744Z</wsu:Expires> 
</wsu:Timestamp> 
</wsse:Security> 
</SOAP-ENV:Header> 
<SOAP-ENV:Body> 
<v1:getDesignationRequest> 
<v1:DesignationCode>SSE</v1:DesignationCode> 
</v1:getDesignationRequest> 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

但我不能够产生这种java代码需要SAML标签以生成所需的实际SOAP请求(在这个问题上)提到的。请帮助..我该如何使用这个Java代码来生成附担保外部服务所需**SAML**请求...

感谢

回答

0

您可以使用Axis 2客户端并添加Rampart以添加SAML支持。您可以这样做吗?

+0

你能不能解释一下请我该如何使用它来创建在问题的开头提到的上述SOAP请求? – 2014-10-31 16:02:05

+0

服务是否可以通过互联网..?如果可用,我可以尝试创建一个虚拟客户端。 – Avi 2014-11-03 12:02:46

+0

该服务在我的本地系统..如果你看看我的问题...我尝试创建请求的Java代码..我成功地创建用户名,密码,随机数和时间戳。无法在需要的请求中创建saml标签(我提到了问题开始时的完整请求)。您能否帮我创建并在Java代码中包含这些标签,以便能够创建完整的请求要求? – 2014-11-03 14:34:53