我正在针对具有以下策略的 wsdl 开发一个 Web 服务客户端
<wsp:Policy xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" wsu:Id="SecurityServiceSignThenEncryptPolicy">
<wsp:ExactlyOne>
<wsp:All>
<sp:AsymmetricBinding>
<wsp:Policy>
<sp:InitiatorToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssX509V3Token10/>
<sp:WssX509V3Token11/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:InitiatorToken>
<sp:RecipientToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Always">
<wsp:Policy>
<sp:WssX509V3Token10/>
<sp:WssX509V3Token11/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:RecipientToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic128Rsa15/>
<sp:Basic256Rsa15/>
<sp:Basic128Sha256Rsa15/>
<sp:Basic256Sha256Rsa15/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
<sp:ProtectTokens/>
<sp:OnlySignEntireHeadersAndBody/>
</wsp:Policy>
</sp:AsymmetricBinding>
<sp:Wss10>
<wsp:Policy>
<sp:MustSupportRefKeyIdentifier/>
<sp:MustSupportRefIssuerSerial/>
<sp:MustSupportRefThumbprint/>
<sp:MustSupportRefEncryptedKey/>
</wsp:Policy>
</sp:Wss10>
<sp:Wss11>
<wsp:Policy>
<sp:MustSupportRefKeyIdentifier/>
<sp:MustSupportRefIssuerSerial/>
<sp:MustSupportRefThumbprint/>
<sp:MustSupportRefEncryptedKey/>
<sp:RequireSignatureConfirmation/>
</wsp:Policy>
</sp:Wss11>
</wsp:All>
</wsp:ExactlyOne>
<wsp:Policy wsu:Id="InputBindingPolicy">
<wsp:ExactlyOne>
<wsp:All>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
<sp:SignedParts>
<sp:Body/>
</sp:SignedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="OutputBindingPolicy">
<wsp:ExactlyOne>
<wsp:All>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
<sp:SignedParts>
<sp:Body/>
</sp:SignedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
如果我使用 SOAP UI 发送请求,我得到
faultstring>These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}AsymmetricBinding: Received Timestamp does not match the requirements
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}X509Token: The received token does not match the token inclusion requirement
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}InitiatorToken
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}RecipientToken
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}IncludeTimestamp: Received Timestamp does not match the requirements
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}EncryptedParts:
{http://schemas.xmlsoap.org/soap/envelope/}Body not ENCRYPTED
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}SignedParts:
{http://schemas.xmlsoap.org/soap/envelope/}Body not SIGNED</faultstring>
所以我启动了一个 CXF 客户端,这是我的代码
public static void main(String[] args) throws MalformedURLException {
URL wsdlURL = new URL("http://localhost:8080/pathToWsdl?wsdl");
QName SERVICE_NAME = new QName("http://webservices.provider.com/", "serviceClient");
Service service = Service.create(wsdlURL, SERVICE_NAME);
executeCall(service);
}
public static void executeCall(Service service) {
//code to get clientInterface;
Client client = ClientProxy.getClient(clientInterface);
Endpoint cxfEndpoint = client.getEndpoint();
Map<String, Object> inProps = new HashMap<String, Object>();
WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
cxfEndpoint.getInInterceptors().add(wssIn);
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.ENCRYPT);
outProps.put(WSHandlerConstants.USER, "keycliente");
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, KeystorePasswordCallback.class.getName());
outProps.put(WSHandlerConstants.SIG_PROP_FILE, "client-crypto.properties");
outProps.put(WSHandlerConstants.ENC_PROP_FILE, "client-crypto.properties");
outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
outProps.put(WSHandlerConstants.ENCRYPTION_USER, "tobias");
outProps.put(WSHandlerConstants.ENC_KEY_TRANSPORT, WSConstants.KEYTRANSPORT_RSA15);
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);
ServiceRequest request= buildRequest();
serviceInterface.method(request);
}
执行此客户端后,我能够更进一步,我现在的问题与我无法满足的 remanet 策略有关。
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}AsymmetricBinding: Received Timestamp does not match the requirements
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}InitiatorToken
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}RecipientToken
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}IncludeTimestamp: Received Timestamp does not match the requirements
有了这些错误,至少我知道签名和加密部分正在工作,但我不知道如何构建收件人令牌和其他东西。
我得到了这个工作。 问题与我如何编码客户端有关。在 WSDL 中配置策略时,最好的方法是加载它并让 CXF 执行魔术。 如果我添加一个中间器,它似乎覆盖了 CXF 步骤或 CXF 不执行某些步骤。有了这段代码,我能够让它工作。
public static void main(String[] args) throws MalformedURLException, DatatypeConfigurationException {
URL wsdlURL = new File("ApiBancosClients.wsdl").toURI().toURL();
QName SERVICE_NAME = new QName("http://webservices.apibancos.debin.com/", "ApiBancosClient");
Service service = Service.create(wsdlURL, SERVICE_NAME);
callApiBancosClientService(service);
}
public static void callApiBancosClientService(Service service) throws DatatypeConfigurationException {
ApiBancosClientInterface apiBancosClientInterface = service.getPort(ApiBancosClientInterface.class);
Client client = ClientProxy.getClient(apiBancosClientInterface);
client.getRequestContext().put(SecurityConstants.ENCRYPT_PROPERTIES, "client-crypto.properties");
client.getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIES, "client-crypto.properties");
client.getRequestContext().put(SecurityConstants.CALLBACK_HANDLER, "com.bp.KeystorePasswordCallback");
client.getRequestContext().put(SecurityConstants.SIGNATURE_USERNAME, "keycliente");
client.getRequestContext().put(SecurityConstants.ENCRYPT_USERNAME, "keyserver");
client.getResponseContext().put(SecurityConstants.ENCRYPT_PROPERTIES, "client-crypto.properties");
client.getResponseContext().put(SecurityConstants.SIGNATURE_PROPERTIES, "client-crypto.properties");
client.getResponseContext().put(SecurityConstants.CALLBACK_HANDLER, "com.bp.KeystorePasswordCallback");
Endpoint cxfEndpoint = client.getEndpoint();
Map<String, Object> inProps = new HashMap<String, Object>();
AvisoNuevoDebinRequest avisoDeNuevoDebin = buildRequest();
apiBancosClientInterface.avisoDeNuevoDebin(avisoDeNuevoDebin);
System.out.println("FINISH");
}
使用SIGNATURE_PARTS并添加时间戳元素,因此将其包含在内。
{元素}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}时间戳
xxxx.put(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;{元素}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}时间戳"(;