我有一个使用WS-Security和 SAML 实现的外部SOAP Web服务... Web服务的SOAP请求如下: -
<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 :(得分:0)
我建议您查看OpenSAML library。它非常受欢迎,受到良好支持,文档齐全 - 您可以在互联网上找到plenty of examples。
答案 1 :(得分:0)
您可以使用Axis 2客户端并添加Rampart以添加SAML支持..您可以这样做吗?
答案 2 :(得分:0)
正如Avi建议我最终使用Axis 2客户端并添加Rampart以添加SAML支持并且它对我有效。
对于参考我在这里做的是链接: -
https://thilinamb.wordpress.com/2009/10/20/saml-2-0-token-profile-support-in-rampart-1-5/
https://axis.apache.org/axis2/java/rampart/setting-up-sts.html