如何使用 CXF 将 wsse:KeyIdentifier 更改为 wsse:Reference
how to change wsse:KeyIdentifier to wsse:Reference with CXF
我正在使用 CXF 3.1.5,试图将 请求 发送到 STS服务器,STS服务器有一个策略,相关部分如下
<wsp:Policy>
<sp:RequireThumbprintReference />
<sp:WssX509V3Token10 />
</wsp:Policy>
所以在request CXF发送到STS服务器,签名密钥 看起来像这样:
<wsse:SecurityTokenReference wsu:Id="...">
<wsse:KeyIdentifier EncodingType="..."ValueType="...#ThumbprintSHA1">...</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
但 我想将 SecurityTokenReference 更改为
<wsse:SecurityTokenReference>
<wsse:Reference URI="..." ValueType="...#**X509v3**"/>
</wsse:SecurityTokenReference>
它指的是 BinarySecurityToken 这是一个 X.509 证书
那我该怎么办?我发现了一些关于 PolicyBasedWSS4JOutInterceptor 和 PolicyBasedWSS4JInInterceptor,但不知道它们是如何工作的。
非常感谢!
您需要由您的服务器接受的 CA 颁发的证书来签署 SOAP 请求。您可以将 CXF 与 WSS4JOutInterceptor
一起使用
这是使用 WSS4J 和 CXF 的配置。省略创建密钥库的部分
设置WSS4J properties(根据您的政策调整)
outProps.put("action", "Signature");
outProps.put("user", certificateAlias);
outProps.put("passwordType", "PasswordText");
outProps.put("signaturePropFile", propertiesFile);
outProps.put("signatureKeyIdentifier","DirectReference");
outProps.put("passwordCallbackRef",clientPasswordCallback);
propertiesFile
包含属性文件的路径,其中配置了密钥库的路径
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=changeit
org.apache.ws.security.crypto.merlin.file=keystore.jks
ClientPasswordCallback
从wss4j回调获取证书密码
public class ClientPasswordCallback implements CallbackHandler {
String password = ...; //Configure the password
public void handle(Callback[] callbacks) {
for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
pc.setPassword(password);
}
}
}
使用 WebService 端口配置 CXF 客户端
Client client = ClientProxy.getClient(port);
Endpoint cxfEndpoint = client.getEndpoint();
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);
//Include LoggingOutInterceptor to log the soap message
cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor());
最后调用您的服务
port.myService();
@pedrofb,非常感谢你的帮助。不幸的是,我仍然有两个 BinarySecurityToken 元素,我无法使用替代策略文件。
但我在这里找到了解决方案:How to get incoming & outgoing soap xml in a simple way using Apache CXF?
它为我提供了一个在 CXF 发送之前编辑肥皂信封的解决方案。不是很好,但这是我得到的最好的解决方案。
我正在使用 CXF 3.1.5,试图将 请求 发送到 STS服务器,STS服务器有一个策略,相关部分如下
<wsp:Policy>
<sp:RequireThumbprintReference />
<sp:WssX509V3Token10 />
</wsp:Policy>
所以在request CXF发送到STS服务器,签名密钥 看起来像这样:
<wsse:SecurityTokenReference wsu:Id="...">
<wsse:KeyIdentifier EncodingType="..."ValueType="...#ThumbprintSHA1">...</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
但 我想将 SecurityTokenReference 更改为
<wsse:SecurityTokenReference>
<wsse:Reference URI="..." ValueType="...#**X509v3**"/>
</wsse:SecurityTokenReference>
它指的是 BinarySecurityToken 这是一个 X.509 证书
那我该怎么办?我发现了一些关于 PolicyBasedWSS4JOutInterceptor 和 PolicyBasedWSS4JInInterceptor,但不知道它们是如何工作的。
非常感谢!
您需要由您的服务器接受的 CA 颁发的证书来签署 SOAP 请求。您可以将 CXF 与 WSS4JOutInterceptor
这是使用 WSS4J 和 CXF 的配置。省略创建密钥库的部分
设置WSS4J properties(根据您的政策调整)
outProps.put("action", "Signature");
outProps.put("user", certificateAlias);
outProps.put("passwordType", "PasswordText");
outProps.put("signaturePropFile", propertiesFile);
outProps.put("signatureKeyIdentifier","DirectReference");
outProps.put("passwordCallbackRef",clientPasswordCallback);
propertiesFile
包含属性文件的路径,其中配置了密钥库的路径
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=changeit
org.apache.ws.security.crypto.merlin.file=keystore.jks
ClientPasswordCallback
从wss4j回调获取证书密码
public class ClientPasswordCallback implements CallbackHandler {
String password = ...; //Configure the password
public void handle(Callback[] callbacks) {
for (int i = 0; i < callbacks.length; i++) {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
pc.setPassword(password);
}
}
}
使用 WebService 端口配置 CXF 客户端
Client client = ClientProxy.getClient(port);
Endpoint cxfEndpoint = client.getEndpoint();
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);
//Include LoggingOutInterceptor to log the soap message
cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor());
最后调用您的服务
port.myService();
@pedrofb,非常感谢你的帮助。不幸的是,我仍然有两个 BinarySecurityToken 元素,我无法使用替代策略文件。
但我在这里找到了解决方案:How to get incoming & outgoing soap xml in a simple way using Apache CXF?
它为我提供了一个在 CXF 发送之前编辑肥皂信封的解决方案。不是很好,但这是我得到的最好的解决方案。