我打算通过SAML令牌策略创建SOAP标头。我编写了一种方法,如下所示:
void addSamlTokenClientPolicy(SOAPMessageContext context){
SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();
if (header == null) {
header = envelope.addHeader();
}
SOAPFactory factory = SOAPFactory.newInstance();
SOAPElement securityElem = factory.createElement(SoapSecurityHeaderConstants.SecurityEle,
SoapSecurityHeaderConstants.prefix, SoapSecurityHeaderConstants.uri);
String samlMetadataFile = "/samlMetadata.xml";
// Initialize the library
DefaultBootstrap.bootstrap();
// Get Parser Pool Manager
BasicParserPool ppMgr = new BasicParserPool();
ppMgr.setNamespaceAware(true);
// Parse Metadata file
InputStream in = CZSoapSecurityHandler.class.getResourceAsStream(samlMetadataFile);
Document inDoc = ppMgr.parse(in);
Element metadataRoot = inDoc.getDocumentElement();
// Get appropriate unmarshaller
UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(metadataRoot);
XMLObject xmlObj = unmarshaller.unmarshall(metadataRoot);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
DOMSource source = new DOMSource(xmlObj.getDOM());
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
String strObject = result.getWriter().toString();
securityElem.setTextContent(strObject);
header.addChildElement(securityElem);
}
文件samlMetadata.xml
的内容如下:
<saml:Assertion Version="2.0"
ID="SAML-8z1f2F9fQ1EjegMIuH11Wg22" IssueInstant="2015-12-17T11:15:50Z"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Issuer>xxx</saml:Issuer>
<saml:Subject>
<saml:NameID
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">username</saml:NameID>
<saml:SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:sender-vouches" />
</saml:Subject>
<saml:AuthnStatement
AuthnInstant="2015-12-17T11:15:50Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password
</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
这里的问题是,它引发以下错误:
客户端从服务器收到SOAP错误:InvalidSecurity:处理WS-Security安全标头时出错。
我非常确定该错误是由于代码securityElem.setTextContent(strObject)
所致,在该代码中,我正在尝试一种设置从XML解析的文本而不是添加子元素的变通方法。请帮忙。
答案 0 :(得分:0)
我想我找到了答案。 代码中唯一缺少的是Marshaller。在代码中添加了以下几行,以将xmlObject填充到SOAPEnvelope中:
XMLObject xmlObj = unmarshaller.unmarshall(metadataRoot);
MarshallerFactory ms = Configuration.getMarshallerFactory();
Marshaller mshaller = ms.getMarshaller(xmlObj);
mshaller.marshall(xmlObj, securityElem);
header.addChildElement(securityElem);