在 CXF 中向请求添加安全性 headers
Adding security headers to request in CXF
我创建了一个基于 wsdl 文件的客户端。
我正在使用以下代码调用 Web 服务:
PrivateService ser = new PrivateService();
PrivatePortType port = ser.getPrivateSOAPPort();
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://192.168.4.48/PrivateSimulator/PrivateWebService.svc");
bindingProvider.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
bindingProvider.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY, "CreateParty");
CreatePartyRequest createReq = new CreatePartyRequest();
createReq.setParam("123456");
createReq.setCallback("http://192.168.5.106:9999/Service");
try {
CreatePartyResponse resp = port.createParty(createReq);
PartyInfo ci = resp.getPartyInfo();
System.out.println(ci.getPartyId());
} catch (WSException e) {
e.printStackTrace();
}
在调用 createParty 时我接受了 "Object reference not set to an instance of an object" 异常消息。
这可能是因为 Web 服务是用 C# 编写的,而且很可能它需要绿洲 headers,它在其中存储用户名和密码值。
我现在可以创建的信封是:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<CreatePartyRequest xmlns="http://teleParty.QQQ.com/CCGW">
<param>10000903</param>
<callback>http://192.168.5.106:9999/Service</callback>
</CreatePartyRequest>
</soap:Body>
</soap:Envelope>
所需的信封如下:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="uuid-2aae5c05-19af-43e6-8814-7d7e7a306d4d-3">
<o:Username>QQQ</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">QQQPass</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CreatePartyRequest xmlns="http://teleParty.QQQ.com/CCGW">
<param>10000903</param>
<callback>http://192.168.5.106:9999/Service</callback>
</CreatePartyRequest>
</s:Body>
</s:Envelope>
如何将那些 headers 和属性添加到请求中?
您需要添加 WSS4JOutInterceptor + 配置它以将 UsernameToken 添加到请求中。请参阅此处称为 "Username Token Authentication":
的部分
您可以像这样设置UsernameToken。您可以看到 PasswordCallback class here.
的实现
public void setOutInterceptor(PrivatePortType port) {
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put("action", "UsernameToken");
outProps.put("user", "QQQ");
outProps.put("passwordType", "PasswordText");
outProps.put("passwordCallbackClass","PasswordCallback");
WSS4JOutInterceptor outInterceptor = new WSS4JOutInterceptor(outProps);
Client client = ClientProxy.getClient(port);
client.getOutInterceptors().add(outInterceptor);
}
PrivateService ser = new PrivateService();
PrivatePortType port = ser.getPrivateSOAPPort();
setOutInterceptor(port);
我创建了一个基于 wsdl 文件的客户端。
我正在使用以下代码调用 Web 服务:
PrivateService ser = new PrivateService();
PrivatePortType port = ser.getPrivateSOAPPort();
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://192.168.4.48/PrivateSimulator/PrivateWebService.svc");
bindingProvider.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
bindingProvider.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY, "CreateParty");
CreatePartyRequest createReq = new CreatePartyRequest();
createReq.setParam("123456");
createReq.setCallback("http://192.168.5.106:9999/Service");
try {
CreatePartyResponse resp = port.createParty(createReq);
PartyInfo ci = resp.getPartyInfo();
System.out.println(ci.getPartyId());
} catch (WSException e) {
e.printStackTrace();
}
在调用 createParty 时我接受了 "Object reference not set to an instance of an object" 异常消息。
这可能是因为 Web 服务是用 C# 编写的,而且很可能它需要绿洲 headers,它在其中存储用户名和密码值。
我现在可以创建的信封是:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<CreatePartyRequest xmlns="http://teleParty.QQQ.com/CCGW">
<param>10000903</param>
<callback>http://192.168.5.106:9999/Service</callback>
</CreatePartyRequest>
</soap:Body>
</soap:Envelope>
所需的信封如下:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="uuid-2aae5c05-19af-43e6-8814-7d7e7a306d4d-3">
<o:Username>QQQ</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">QQQPass</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CreatePartyRequest xmlns="http://teleParty.QQQ.com/CCGW">
<param>10000903</param>
<callback>http://192.168.5.106:9999/Service</callback>
</CreatePartyRequest>
</s:Body>
</s:Envelope>
如何将那些 headers 和属性添加到请求中?
您需要添加 WSS4JOutInterceptor + 配置它以将 UsernameToken 添加到请求中。请参阅此处称为 "Username Token Authentication":
的部分您可以像这样设置UsernameToken。您可以看到 PasswordCallback class here.
的实现public void setOutInterceptor(PrivatePortType port) {
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put("action", "UsernameToken");
outProps.put("user", "QQQ");
outProps.put("passwordType", "PasswordText");
outProps.put("passwordCallbackClass","PasswordCallback");
WSS4JOutInterceptor outInterceptor = new WSS4JOutInterceptor(outProps);
Client client = ClientProxy.getClient(port);
client.getOutInterceptors().add(outInterceptor);
}
PrivateService ser = new PrivateService();
PrivatePortType port = ser.getPrivateSOAPPort();
setOutInterceptor(port);