...
Code Block |
---|
|
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.jaxws.EndpointImpl;
EndpointImpl jaxWsEndpoint = (EndpointImpl) Endpoint.publish("http://host/service",
myServiceImpl);
Endpoint cxfEndpoint = jaxWsEndpoint.getServer().getEndpoint();
|
...
On the client side, you can obtain a reference to the CXF endpoint using the ClientProxy helper:
Code Block |
---|
|
import org.apache.cxf.frontend.ClientProxy;
...
GreeterService gs = new GreeterService();
Greeter greeter = gs.getGreeterPort();
...
org.apache.cxf.endpoint.Client client = org.apache.cxf.frontend.ClientProxy.getClient(greeter);
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();
|
...
Code Block |
---|
|
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
...
Map<String,Object> inProps= new HashMap<String,Object>();
... // how to configure the properties is outlined below;
WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
cxfEndpoint.getInInterceptors().add(wssIn);
cxfEndpoint.getInInterceptors().add(new SAAJInInterceptor()); // 2.0.x only; not needed in 2.1+
Map<String,Object> outProps = new HashMap<String,Object>();
... // how to configure the properties is outlined below;
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);
cxfEndpoint.getOutInterceptors().add(new SAAJOutInterceptor()); // 2.0.x only; not needed in 2.1+
|
Spring XML Configuration
If you're using Spring to build endpoints (e.g., web services running on a servlet container such as Tomcat), you can easily accomplish the above using your bean definitions instead.
...
Code Block |
---|
|
<beans
...
xmlns:util="http://www.springframework.org/schema/util"
...
xsi:schemaLocation="
...
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
...
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry value="UsernameToken">
<key>
<util:constant
static-field="org.apache.ws.security.handler.WSHandlerConstants.ACTION"/>
</key>
</entry>
...
</map>
</constructor-arg>
</bean>
...
|
...
Code Block |
---|
|
import org.apache.cxf.ws.security.wss4j.CryptoCoverageChecker;
import org.apache.cxf.ws.security.wss4j.CryptoCoverageChecker.XPathExpression;
import org.apache.cxf.ws.security.wss4j.CryptoCoverageUtil.CoverageScope;
import org.apache.cxf.ws.security.wss4j.CryptoCoverageUtil.CoverageType;
Map<String, String> prefixes = new HashMap<String, String>();
prefixes.put("ser", "http://www.sdj.pl");
prefixes.put("soap", "http://schemas.xmlsoap.org/soap/envelope/");
List<XPathExpression> xpaths = Arrays.asList(
new XPathExpression("//ser:Header", CoverageType.SIGNED,
CoverageScope.ELEMENT),
new XPathExpression("//soap:Body", CoverageType.ENCRYPTED,
CoverageScope.CONTENT));
CryptoCoverageChecker checker = new CryptoCoverageChecker(prefixes, xpaths);
|
...
Code Block |
---|
|
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
...
<!-- Redefines the action for SAMLTokenSigned
to use a custom implementation. -->
<entry key="wss4j.action.map">
<map key-type="java.lang.Integer" value-type="java.lang.Object">
<entry key="0x10" value-ref="mySamlTokenSignedAction"/>
</map>
</entry> ...
</map>
</constructor-arg>
</bean>
|
...
Code Block |
---|
inProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
// Password type : plain text
inProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
// for hashed password use:
//properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
// Callback used to retrieve password for given user.
inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
ServerPasswordHandler.class.getName());
|
...
Code Block |
---|
|
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class ServerPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException, throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
if (pc.getIdentifergetIdentifier().equals("joe")) {
// set the password on the callback. This will be compared to the
// password which was sent from the client.
pc.setPassword("password");
}
}
}
|
...
Code Block |
---|
|
public class ServerPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
if (pc.getIdentifer().equals("joe") {
if (!pc.getPassword().equals("password")) {
throw new IOException("wrong password");
}
}
}
}
|
...
Code Block |
---|
outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
// Specify our username
outProps.put(WSHandlerConstants.USER, "joe");
// Password type : plain text
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
// for hashed password use:
//properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
// Callback used to retrieve password for given user.
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
ClientPasswordHandler.class.getName());
|
...
Code Block |
---|
|
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class ClientPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
// set the password for our message.
pc.setPassword("password");
}
}
|
...
Code Block |
---|
keytool -genkey -alias myAlias -keypass myAliasPassword -keystore \
privatestore.jks \
-storepass keyStorePassword -dname "cn=myAlias" -keyalg RSA
|
...
Code Block |
---|
keytool -selfcert -alias myAlias -keystore privatestore.jks \
-storepass keyStorePassword -keypass myAliasPassword
|
...
Code Block |
---|
keytool -export -alias myAlias -file key.rsa -keystore privatestore.jks \
-storepass keyStorePassword
|
...
Code Block |
---|
keytool -import -alias myAlias -file key.rsa -keystore publicstore.jks \
-storepass keyStorePassword
|
...
Code Block |
---|
|
outProps.put(WSHandlerConstants.ACTION, "Signature");
outProps.put(WSHandlerConstants.USER, "myAlias");
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
ClientCallbackHandler.class.getName());
outProps.put(WSHandlerConstants.SIG_PROP_FILE, "client_sign.properties");
|
...
Tip |
---|
|
For X.509 support you will normally have multiple actions, e.g. Encryption with Signature. For these cases, just space-separate the actions in the ACTION property as follows: Code Block |
---|
|
outProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.TIMESTAMP + " " +
WSHandlerConstants.SIGNATURE + " " +
WSHandlerConstants.ENCRYPT);
|
Alternatively, you may space-separate the string literals you see above in the Spring configuration (e.g., "Signature Encrypt") |
...