Skip to end of metadata
Go to start of metadata

WS-Security overview

WS-Security provides the means to secure your services beyond transport level protocols such as HTTPS. Through a number of standards such as XML-Encryption, and headers defined in the WS-Security standard, it allows you to:

  • Pass authentication tokens between services.
  • Encrypt messages or parts of messages.
  • Sign messages.
  • Timestamp messages.

WS-Security makes heavy use of public and private key cryptography. It is helpful to understand these basics to really understand how to configure WS-Security. With public key cryptography, a user has a pair of public and private keys. These are generated using a large prime number and a key function.

The keys are related mathematically, but cannot be derived from one another. With these keys we can encrypt messages. For example, if Bob wants to send a message to Alice, he can encrypt a message using her public key. Alice can then decrypt this message using her private key. Only Alice can decrypt this message as she is the only one with the private key.

Messages can also be signed. This allows you to ensure the authenticity of the message. If Alice wants to send a message to Bob, and Bob wants to be sure that it is from Alice, Alice can sign the message using her private key. Bob can then verify that the message is from Alice by using her public key.

JBoss WS-Security support

JBoss Web Services supports many real world scenarios requiring WS-Security functionalities. This includes signature and encryption support through X509 certificates, authentication and authorization through username tokens as well as all ws-security configurations covered by WS-SecurityPolicy specification.

As well as for other WS-* features, the core of WS-Security functionalities is provided through the Apache CXF engine. On top of that the JBossWS integration adds few configuration enhancements to simplify the setup of WS-Security enabled endpoints.

Apache CXF WS-Security implementation

Apache CXF features a top class WS-Security module supporting multiple configurations and easily extendible.

The system is based on interceptors that delegate to Apache WSS4J for the low level security operations. Interceptors can be configured in different ways, either through Spring configuration files or directly using Apache CXF client API. Please refer to the Apache CXF documentation if you're looking for more details.

Recent versions of Apache CXF, however, introduced support for WS-Security Policy, which aims at moving most of the security configuration into the service contract (through policies), so that clients can easily be configured almost completely automatically from that. This way users do not need to manually deal with configuring / installing the required interceptors; the Apache CXF WS-Policy engine internally takes care of that instead.

WS-Security Policy support

WS-SecurityPolicy describes the actions that are required to securely communicate with a service advertised in a given WSDL contract. The WSDL bindings / operations reference WS-Policy fragments with the security requirements to interact with the service. The WS-SecurityPolicy specification allows for specifying things like asymmetric/symmetric keys, using transports (https) for encryption, which parts/headers to encrypt or sign, whether to sign then encrypt or encrypt then sign, whether to include timestamps, whether to use derived keys, etc.

However some mandatory configuration elements are not covered by WS-SecurityPolicy, basically because they're not meant to be public / part of the published endpoint contract; those include things such as keystore locations, usernames and passwords, etc. Apache CXF allows configuring these elements either through Spring xml descriptors or using the client API / annotations. Below is the list of supported configuration properties:

ws-security.username The username used for UsernameToken policy assertions
ws-security.password The password used for UsernameToken policy assertions. If not specified, the callback handler will be called.
ws-security.callback-handler The WSS4J security CallbackHandler that will be used to retrieve passwords for keystores and UsernameTokens.
ws-security.signature.properties The properties file/object that contains the WSS4J properties for configuring the signature keystore and crypto objects
ws-security.encryption.properties The properties file/object that contains the WSS4J properties for configuring the encryption keystore and crypto objects
ws-security.signature.username The username or alias for the key in the signature keystore that will be used. If not specified, it uses the the default alias set in the properties file. If that's also not set, and the keystore only contains a single key, that key will be used.
ws-security.encryption.username The username or alias for the key in the encryption keystore that will be used. If not specified, it uses the the default alias set in the properties file. If that's also not set, and the keystore only contains a single key, that key will be used. For the web service provider, the useReqSigCert keyword can be used to accept (encrypt to) any client whose public key is in the service's truststore (defined in ws-security.encryption.properties.)
ws-security.signature.crypto Instead of specifying the signature properties, this can point to the full WSS4J Crypto object. This can allow easier "programmatic" configuration of the Crypto information."
ws-security.encryption.crypto Instead of specifying the encryption properties, this can point to the full WSS4J Crypto object. This can allow easier "programmatic" configuration of the Crypto information."
ws-security.enable.streaming Enable streaming (StAX based) processing of WS-Security messages

Here is an example of configuration using the client API:

Please refer to the Apache CXF documentation for additional configuration details.

JBossWS configuration additions

In order for removing the need of Spring on server side for setting up WS-Security configuration properties not covered by policies, the JBossWS integration allows for getting those pieces of information from a defined endpoint configuration. Endpoint configurations can include property declarations and endpoint implementations can be associated with a given endpoint configuration using the @EndpointConfig annotation.

Apache CXF annotations

The JBossWS configuration additions allow for a descriptor approach to the WS-Security Policy engine configuration. If you prefer to provide the same information through an annotation approach, you can leverage the Apache CXF @org.apache.cxf.annotations.EndpointProperties annotation:

Examples

In this section some sample of WS-Security service endpoints and clients are provided. Please note they're only meant as tutorials; you should really careful isolate the ws-security policies / assertion that best suite your security needs before going to production environment.

The following sections provide directions and examples on understanding some of the configuration options for WS-Security engine. Please note the implementor remains responsible for assessing the application requirements and choosing the most suitable security policy for them.

Signature and encryption

Endpoint

First of all you need to create the web service endpoint using JAX-WS. While this can generally be achieved in different ways, it's required to use a contract-first approach when using WS-Security, as the policies declared in the wsdl are parsed by the Apache CXF engine on both server and client sides. So, here is an example of WSDL contract enforcing signature and encryption using X 509 certificates (the referenced schema is omitted):

The service endpoint can be generated using the wsconsume tool and then enriched with a @EndpointConfig annotation:

The referenced jaxws-endpoint-config.xml descriptor is used to provide a custom endpoint configuration with the required server side configuration properties; this tells the engine which certificate / key to use for signature / signature verification and for encryption / decryption:

... the bob.properties configuration file is also referenced above; it includes the WSS4J Crypto properties which in turn link to the keystore file, type and the alias/password to use for accessing it:

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=password
org.apache.ws.security.crypto.merlin.keystore.alias=bob
org.apache.ws.security.crypto.merlin.keystore.file=bob.jks

A callback handler for the letting Apache CXF access the keystore is also provided:

Assuming the bob.jks keystore has been properly generated and contains Bob's (server) full key (private/certificate + public key) as well as Alice's (client) public key, we can proceed to packaging the endpoint. Here is the expected content (the endpoint is a POJO one in a war archive, but EJB3 endpoints in jar archives are of course also supported):

alessio@inuyasha /dati/jbossws/stack/cxf/trunk $ jar -tvf ./modules/testsuite/cxf-tests/target/test-libs/jaxws-samples-wsse-policy-sign-encrypt.war
     0 Thu Jun 16 18:50:48 CEST 2011 META-INF/
   140 Thu Jun 16 18:50:46 CEST 2011 META-INF/MANIFEST.MF
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/
   586 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/web.xml
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/basic/
  1687 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/basic/KeystorePasswordCallback.class
   383 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/basic/ServiceIface.class
  1070 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/basic/ServiceImpl.class
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/
   705 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/SayHello.class
  1069 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/SayHelloResponse.class
  1225 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/jaxws-endpoint-config.xml
     0 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/wsdl/
  4086 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/wsdl/SecurityService.wsdl
   653 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/wsdl/SecurityService_schema1.xsd
  1820 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/classes/bob.jks
   311 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/classes/bob.properties

As you can see, the jaxws classes generated by the tools are of course also included, as well as a basic web.xml referencing the endpoint bean:

If you're deploying the endpoint archive to JBoss Application Server 7, remember to add a dependency to org.apache.ws.security module in the MANIFEST.MF file.
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 17.0-b16 (Sun Microsystems Inc.)
Dependencies: org.apache.ws.security

Client

You start by consuming the published WSDL contract using the wsconsume tool on client side too. Then you simply invoke the the endpoint as a standard JAX-WS one:

As you can see, the WS-Security properties are set in the request context. Here the KeystorePasswordCallback is the same as on server side above, you might want/need different implementation in real world scenarios, of course.
The alice.properties file is the client side equivalent of the server side bob.properties and references the alice.jks keystore file, which has been populated with Alice's (client) full key (private/certificate + public key) as well as Bob's (server) public key.

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=password
org.apache.ws.security.crypto.merlin.keystore.alias=alice
org.apache.ws.security.crypto.merlin.keystore.file=META-INF/alice.jks

The Apache CXF WS-Policy engine will digest the security requirements in the contract and ensure a valid secure communication is in place for interacting with the server endpoint.

Endpoint serving multiple clients

The server side configuration described above implies the endpoint is configured for serving a given client which a service agreement has been established for. In some real world scenarios though, the same server might be expected to be able to deal with (including decrypting and encrypting) messages coming from and being sent to multiple clients. Apache CXF supports that through the useReqSigCert value for the ws-security.encryption.username configuration parameter.

Of course the referenced server side keystore then needs to contain the public key of all the clients that are expected to be served.

Authentication and authorization

The Username Token Profile can be used to provide client's credentials to a WS-Security enabled target endpoint.

Apache CXF provides means for setting basic password callback handlers on both client and server sides to set/check passwords; the ws-security.username and ws-security.callback-handler properties can be used similarly as shown in the signature and encryption example. Things become more interesting when requiring a given user to be authenticated (and authorized) against a security domain on the target JBoss Application Server.

On server side, you need to install two additional interceptors that act as bridges towards the application server authentication layer:

  • an interceptor for performing authentication and populating a valid SecurityContext; the provided interceptor should extend org.apache.cxf.ws.interceptor.security.AbstractUsernameTokenInInterceptor, in particular JBossWS integration comes with org.jboss.wsf.stack.cxf.security.authentication.SubjectCreatingInterceptor for this;
  • an interceptor for performing authorization; CXF requires that to extend org.apache.cxf.interceptor.security.AbstractAuthorizingInInterceptor, for instance the SimpleAuthorizingInterceptor can be used for simply mapping endpoint operations to allowed roles.

So, here follows an example of WS-SecurityPolicy endpoint using Username Token Profile for authenticating through the JBoss Application Server security domain system.

Endpoint

As in the other example, we start with a wsdl contract containing the proper WS-Security Policy:

If you want to send hash / digest passwords, you can use a policy such as what follows:

Please note the specified JBoss security domain needs to be properly configured for computing digests.

The service endpoint can be generated using the wsconsume tool and then enriched with a @EndpointConfig annotation and @InInterceptors annotation to add the two interceptors mentioned above for JAAS integration:

The POJOEndpointAuthorizationInterceptor is included into the deployment and deals with the roles cheks:

The jaxws-endpoint-config.xml descriptor is used to provide a custom endpoint configuration with the required server side configuration properties; in particular for this Username Token case that's just a CXF configuration option for leaving the username token validation to the configured interceptors:

In order for requiring a given JBoss security domain to be used to protect access to the endpoint (a POJO one in this case), we declare that in a jboss-web.xml descriptor (the JBossWS security domain is used):

Finally, the web.xml is as simple as usual:

The endpoint is packaged into a war archive, including the JAXWS classes generated by wsconsume:

alessio@inuyasha /dati/jbossws/stack/cxf/trunk $ jar -tvf ./modules/testsuite/cxf-tests/target/test-libs/jaxws-samples-wsse-policy-username-jaas.war
     0 Thu Jun 16 18:50:48 CEST 2011 META-INF/
   155 Thu Jun 16 18:50:46 CEST 2011 META-INF/MANIFEST.MF
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/
   585 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/web.xml
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaas/
   982 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaas/POJOEndpointAuthorizationInterceptor.class
   412 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaas/ServiceIface.class
  1398 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaas/ServiceImpl.class
     0 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/
   701 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/GreetMe.class
  1065 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/GreetMeResponse.class
   705 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/SayHello.class
  1069 Thu Jun 16 18:50:48 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/SayHelloResponse.class
   556 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/jaxws-endpoint-config.xml
   241 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/jboss-web.xml
     0 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/wsdl/
  3183 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/wsdl/SecurityService.wsdl
  1012 Thu Jun 16 18:50:44 CEST 2011 WEB-INF/wsdl/SecurityService_schema1.xsd
If you're deploying the endpoint archive to JBoss Application Server 7, remember to add a dependency to org.apache.ws.security and org.apache.cxf module (due to the @InInterceptor annotation) in the MANIFEST.MF file.
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 17.0-b16 (Sun Microsystems Inc.)
Dependencies: org.apache.ws.security,org.apache.cxf

Client

Here too you start by consuming the published WSDL contract using the wsconsume tool. Then you simply invoke the the endpoint as a standard JAX-WS one:

The UsernamePasswordCallback class is shown below and is responsible for setting the passwords on client side just before performing the invocations:

If everything has been done properly, you should expect to calls to sayHello() fail when done with user "snoopy" and pass with user "kermit" (and credential "thefrog"); moreover, you should get an authorization error when trying to call greetMe() with user "kermit", as that does not have the "snoopies" role.

Secure transport

Another quite common use case is using WS-Security Username Token Profile over a secure transport (HTTPS). A scenario like this is implemented similarly to what's described in the previous example, except for few differences explained below.

First of all, here is an excerpt of a wsdl wth a sample security policy for Username Token over HTTPS:

The endpoint then needs of course to be actually available on HTTPS only, so we have a web.xml setting the transport-guarantee such as below:

Secure conversation

Apache CXF supports WS-SecureConversation specification, which is about improving performance by allowing client and server to negotiate initial security keys to be used for later communication encryption/signature. This is done by having two policies in the wsdl contract, an outer one setting the security requirements to actually communicate with the endpoint and a bootstrap one, related to the communication for establishing the secure conversation keys. The client will be automatically sending an initial message to the server for negotiating the keys, then the actual communication to the endpoint takes place. As a consequence, Apache CXF needs a way to specify which WS-Security configuration properties are intended for the bootstrap policy and which are intended for the actual service policy. To accomplish this, properties intended for the bootstrap policy are appended with .sct.

Labels:
where where Delete
is is Delete
sourcde sourcde Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Sep 26, 2012

    Hi,

    I'm using JBOSS 7.2.0.Alpha1 nightly build.

    When i try your authentication and authorization example, i get the error below on jboss log. I couldn't understand the reason???

    1. Sep 27, 2012

      I add some dependencies to the manifest file like below:

      Dependencies: org.apache.cxf export, org.apache.cxf.impl export, org.apache.ws.security export, org.codehaus.woodstox export

  2. Oct 01, 2012

    Please post on the forums for user assistance. In any case, this looks like an issue with the contents of the request message, which is possibly missing the required username token or something.

    1. Nov 06, 2012

      Hi Alessio, could you help me with this? I will apreciate your suggestions

  3. Feb 18, 2015

    Hi Alessio, can you help me with this?