Reputation: 1040
I am trying to use Apache CXF with policy based WS-Security. The WSDL file tells the client to first get a token from a Security Token Service. This Request needs to be signed with a certificate i got from the service provider. The STS is implemented using ADFS.
My current code looks like this:
BindingProvider bindingProvider = (BindingProvider) port;
Map<String, Object> requestContext = bindingProvider.getRequestContext();
// signing configuration
Properties cryptoProperties = new Properties();
cryptoProperties.put(Merlin.PREFIX + Merlin.KEYSTORE_TYPE, "pkcs12");
cryptoProperties.put(Merlin.PREFIX + Merlin.KEYSTORE_FILE, "C:\\[...]\\keystore.p12");
cryptoProperties.put(Merlin.PREFIX + Merlin.KEYSTORE_PASSWORD, KEYSTORE_KEY);
cryptoProperties.put(Merlin.PREFIX + Merlin.KEYSTORE_ALIAS, KEYSTORE_ALIAS);
requestContext.put(SecurityConstants.SIGNATURE_CRYPTO, new Merlin(cryptoProperties, Loader.getClassLoader(Merlin.class), null));
requestContext.put(SecurityConstants.SIGNATURE_USERNAME, KEYSTORE_ALIAS);
requestContext.put(SecurityConstants.CALLBACK_HANDLER,
new CallbackHandler() {
@Override
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
pc.setPassword(KEYSTORE_KEY);
}
});
// additional configuration
requestContext.put(SecurityConstants.STS_CLIENT_SOAP12_BINDING, "true");
Currently i get the error ID3035: The request was not valid or is malformed.
The policy looks like this
<wsp:Policy wsu:Id="[...]">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false"/>
</wsp:Policy>
</sp:TransportToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
</wsp:Policy>
</sp:TransportBinding>
<sp:EndorsingSupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:RequireThumbprintReference/>
<sp:WssX509V3Token10/>
</wsp:Policy>
</sp:X509Token>
<mssp:RsaToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never" wsp:Optional="true" xmlns:mssp="http://schemas.microsoft.com/ws/2005/07/securitypolicy"/>
<sp:SignedParts>
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
</sp:SignedParts>
</wsp:Policy>
</sp:EndorsingSupportingTokens>
<sp:Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:MustSupportRefThumbprint/>
</wsp:Policy>
</sp:Wss11>
<sp:Trust10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:MustSupportIssuedTokens/>
<sp:RequireClientEntropy/>
<sp:RequireServerEntropy/>
</wsp:Policy>
</sp:Trust10>
<wsaw:UsingAddressing/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
The example of the service provider tells me to sign the request this way:
<Security>
<BinarySecurityToken Id="uuid-something">[...]</BinarySecurityToken>
<Signature>
[...]
<KeyInfo>
<SecurityTokenReference>
<Reference URI="#uuid-something"></Reference>
</SecurityTokenReference>
</KeyInfo>
</Signature>
</Security>
My request looks like this:
<Security>
<BinarySecurityToken>[...]</BinarySecurityToken>
<Signature>
[...]
<KeyInfo>
<SecurityTokenReference>
<KeyIdentifier>[...]</KeyIdentifier>
</SecurityTokenReference>
</KeyInfo>
</Signature>
</Security>
How do i manage to get a Reference instead of the KeyIdentifier?
Searching the internet i think i somehow have to set WSHandlerConstants.SIG_KEY_ID to DirectReference like stated in this blog-post. The problem is i don't know how to do that with the policy based approach...
Another difference to the working example is, that my request contains <Renewing />, which does not work with ADFS like stated in this answer.
<wst:RequestSecurityToken>
[...]
<wst:Renewing/>
</wst:RequestSecurityToken>
Upvotes: 1
Views: 663
Reputation: 1900
What does the policy look like? It should tell CXF how to reference the signing key, without any configuration changes.
The policy clearly tells CXF to use a Thumbprint Reference to refer to the signing key, so CXF is doing the right thing as per the policy. If you want to use a direct reference, then remove the "RequireThumbprintReference" policy.
You can avoid sending the Renewing Element by setting the "sendRenewing" of the STSClient to "false".
Upvotes: 2