Chapter 30. Credentials for Web Services Security
- 30.1. About Web Services Security Configuration
- 30.2. WSS4J Interceptors and WSRP
- 30.3. WS-Security Consumer Configuration
- 30.4. Producer Configuration
- 30.5. Configuring WSRP using the User name Token and User Propagation
- 30.6. Securing WSRP Endpoints using Encryption and Signing
- 30.7. Configuring WSRP using User name Token, Encryption and Signing with User Propagation
When the consumer sends the user credentials to the producer, it is sending the credentials for the currently authenticated user in the consumer. This makes signing in to remote portlets transparent to end users, but also requires that the producer and consumer use the same credentials. This means that the user name and password must be the same and valid on both servers.
The recommended approach for this situation would be to use a common LDAP configuration. See the LDAP Integration chapter in the Administration and Configuration Guide to correctly configure LDAP on the portal.
30.1. About Web Services Security Configuration
JBoss Enterprise Application Platform 6 uses a different web service implementation than the previous versions: it is now uses the JBossWS CXF Stack instead of the JBossWS Native Stack. Due to these changes, the way we configure WS-Security for WSRP with the portal on JBoss Enterprise Application Platform 6 has changed.
CXF uses interceptors to extend and configure its behavior. There are two main types of interceptors: inInterceptors and outInterceptors. InInterceptors are invoked for communication coming into the client or server, while outInterceptors are invoked when the client or server sends a message.
So for the WSRP case, the communication from the consumer to the producer is governed by the consumer's OutInterceptor and the producer's InInterceptors. The communication from the producer to the consumer is governed by the producer's OutInterceptor and the consumer's InInterceptor. This may mean having to configure 4 Interceptors.
When dealing with user propagation, only the consumer sends the user credentials to the producer. So Username Tokens only need to be configured for the consumer's OutInterceptor and the producer's InInterceptor.
Consider encrypting the message from the consumer to the producer and also the message from the producer to the consumer. This means that encryption properties must be configured for all 4 interceptors.
See the CXF Documentation for more details on interceptors and their types: http://cxf.apache.org/docs/interceptors.html
To support ws-security, the portal uses CXF's WSS4J Interceptors which handle all ws-security related tasks. See the CXF Documentation for more details: http://cxf.apache.org/docs/ws-security.html
Note
We only support one ws-security configuration option for the producer. All consumers accessing the producer will have to conform to this security constraint. This means if the producer requires encryption, all consumers will be required to encrypt their messages when accessing the producer.
We only support one ws-security configuration option to be used by all the consumers. A consumer has the option to enable or disable ws-security, which allows for one or more consumers to use ws-security while the others do not.
30.2. WSS4J Interceptors and WSRP
The WSS4J Interceptors are configured using property files. WSRP looks for specific property files to know whether or not in/out interceptors must be added and configured for either consumers or producer.
Theses files are located in the
standalone/configuration/jpp/wsrp/cxf/ws-security directory.
Consumer-specific files are in the consumer subdirectory while producer-specific files are located in the producer subdirectory. To add and configure a WSS4J interceptor, add the proper configuration file in the proper directory. If no configuration file is found for a specific interceptor type, then no such interceptor will be added.
“In” interceptors are configured using WSS4JInInterceptor.properties files while “out” interceptors are configured using WSS4JOutInterceptor.properties files.
Table 30.1. Files needed to configure interceptor for WSRP
| Side | Interceptor Type | Configuration File |
|---|---|---|
| Consumer | IN | standalone/configuration/gatein/wsrp/cxf/ws-security/consumer/WSS4JInInterceptor.properties |
| OUT | standalone/configuration/gatein/wsrp/cxf/ws-security/consumer/WSS4JOutInterceptor.properties | |
| Producer | IN | standalone/configuration/gatein/wsrp/cxf/ws-security/producer/WSS4JInInterceptor.properties |
| OUT | standalone/configuration/gatein/wsrp/cxf/ws-security/producer/WSS4JOutInterceptor.properties |
See the CXF or WSS4J documentation for instructions and options available for each type of interceptor.
30.2.1. User Propagation
User propagation can be configured to be used over WSRP with ws-security. What this means is that a user logged into a consumer can have their credentials propagated over to the producer. This allows the producer to authenticate the user and any portlet on the producer (a remote portlet from the consumer's perspective) will view the user as being properly authenticated. This allows for remote portlets to access things like user information.
Note
This only works if the user's credentials on the producer and consumer are the same. This may require using a common authentication mechanism, such as LDAP.
This requires some special options when configuring the producer and server.
30.3. WS-Security Consumer Configuration
In order to configure ws-security on the consumer side, you will have to configure the WSS4J Interceptors as seen above. This will require having to configure the WSS4JInInterceptor and/or WSS4JOutInterceptor. You will also need to check the 'Enable WS-Security' checkbox on the WSRP Admin Portlet for the consumer configuration to take effect.
30.3.1. Portal-specific Configuration Options for User Propagation
In order to handle portal user propagation across ws-security, a number of configuration options have been created, which are recommended for the consumer's WSS4JOutInterceptor.
- Custom user option
user=gtn.current.user
This option sets the user property to the currently authenticated user on the consumer.- Custom action option
action=gtn.UsernameToken.ifCurrentUserAuthenticated
If a user is currently authenticated, it will replace the gtn.UsernameToken.ifCurrentUserAuthenticated with UsernameToken. If the current user is an unauthenticated user, gtn.UsernameToken.ifCurrentUserAuthenticated will be removed from the action list. If no other actions are specified, then the WSS4J interceptor will not be added to the consumer. This allows you to only use ws-security when dealing with authenticated users, and not for anonymous users.Note
This requires that the user option is set to 'gtn.current.user'- Custom PasswordCallbackClass
action=gtn.UsernameToken.ifCurrentUserAuthenticated
To set the password for the username token, we need to specify the password in a callback class. See the cxf ws-security documentation for more details http://cxf.apache.org/docs/ws-security.htmlA special callback class has already been created which handles this for you: CurrentUserPasswordCallback. This class will retrieve the currently authenticated user's password and set this as the password in the callback object.passwordCallbackClass=org.gatein.wsrp.wss.cxf.consumer.CurrentUserPasswordCallback
30.4. Producer Configuration
The configuration of the producer is similar to that of the consumer. It also requires having to configure the WSS4JInInterceptor and/or WSS4JOutInterceptor.
30.4.1. Special Configuration Options for User Propagation
To correctly propagate user information on the producer-side, use GTNSubjectCreatingInterceptor instead of a regular WSS4JInInterceptor. This portal-specific "in" interceptor is an extension of the traditional WSS4JInInterceptor and therefore can be configured similarly and accept the same configuration properties. To use the GTNSubjectCreatingInterceptor, create a property file at
standalone/configuration/gatein/wsrp/cxf/ws-security/producer/GTNSubjectCreatingInterceptor.properties instead of the regular WSS4JInInterceptor.properties file.
This Interceptor will handle the ws-security headers and retrieve the users credentials. It will then use these credentials to perform a login on the producer site, thus authenticating the user on the producer and makes the user available to remote portlets.
Note
This class also extends org.jboss.wsf.stack.cxf.security.authentication.SubjectCreatingInterceptor and can accept the same properties this class normally accepts. See the JBossWS documentation for options and more information.
30.4.2. Custom 'action' option
action=gtn.UsernameToken.ifAvailable
When this option is activated, the interceptor will set the action to 'UsernameToken' when the received SOAP message contains ws-security headers. If no ws-security header is included in the message, then no action is taken and the interceptor is not run. This is useful for dealing with authenticated and unauthenticated users trying to access the producer.
30.5. Configuring WSRP using the User name Token and User Propagation
30.5.1. Producer Setup
- create the following file:
standalone/configuration/gatein/wsrp/cxf/ws-security/producer/GTNSubjectCreatingInterceptor.properties - set the content of
GTNSubjectCreatingInterceptor.propertiescreated in step 1 to:action=gtn.UsernameToken.ifAvailable
- start the producer server
Warning
This example configuration does not encrypt the message. This means the username and password will be sent between the producer and consumer in plain text. This is a security concern and is only being shown as a simple example. It is up to administrators to properly configure the WSS4J Interceptors to encrypt messages or to only use https communication between the producer and consumer.
30.5.2. Consumer Setup
Procedure 30.1. Configuring a Consumer
- Create the following file:
standalone/configuration/gatein/wsrp/cxf/ws-security/consumer/WSS4JOutInterceptor.properties - Set the content of the
WSS4JOutInterceptor.propertiesto the following parameters:passwordType=PasswordText user=gtn.current.user action=gtn.UsernameToken.ifCurrentUserAuthenticated passwordCallbackClass=org.gatein.wsrp.wss.cxf.consumer.CurrentUserPasswordCallback
- Start the consumer server.
- In the WSRP admin portlet, click the 'enable ws-security' checkbox
- Access a remote portlet (for example, the user identity portlet included as an example portlet) and verify that the authenticated user is the same as the one on the consumer.
30.6. Securing WSRP Endpoints using Encryption and Signing
30.6.1. Sample Configuration for securing the Endpoints using Encryption and Signing
The following steps outline how to configure the producer and consumer to encrypt and sign SOAP messages passed between the producer and consumer. This example only deals with SOAP messages being sent between the producer and consumer, and not with user propagation.
Note
Some of the configuration options specified here are based on the content at http://cxf.apache.org/docs/ws-security.html and http://www.jroller.com/gmazza/entry/cxf_x509_profile More information may be available at these sites.
30.6.2. Password Callback Class
WSS4J uses a Java class to specify the password when performing any security related actions. For the purpose of these encryption and signing examples, we will use the same password for the producer's and consumer's keystore (wsrpAliasPassword). This simplifies configuration because one password callback class can be used for both the producer and consumer.
Example 30.1. Example test.TestCallbackHandler Class
package test;   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; import org.gatein.wsrp.wss.cxf.consumer.CurrentUserPasswordCallback;   public class TestCallbackHandler implements CallbackHandler {       @Override     public void handle(Callback[] callbacks) throws IOException,             UnsupportedCallbackException     {           //First check if we have any user name token call backs to add.         //NOTE: only needed if using username tokens, and you want the currently authenticated users password added         CurrentUserPasswordCallback currentUserPasswordCallback = new CurrentUserPasswordCallback();         currentUserPasswordCallback.handle(callbacks);           for (Callback callback: callbacks)         {             if (callback instanceof WSPasswordCallback)             {                 WSPasswordCallback wsPWCallback = (WSPasswordCallback)callback;                 // since the CurrentUserPasswordCallback already handles the USERNAME_TOKEN case, we don't want to set it in this case                 if (wsPWCallback.getUsage() != WSPasswordCallback.USERNAME_TOKEN)                 {                     wsPWCallback.setPassword("wsrpAliasPassword");                 }             }         }     } }
Note
CallbackHandler implementations are provided to the portal using the standard Java ServiceLoader infrastructure. CallbackHandler implementations need to be bundled in a jar containing a file
META-INF/services/javax.security.auth.callback.CallbackHandler specifying the fully qualified name of the CallbackHandler implementation class. This jar then needs to be put in the gatein/extensions directory of the portal installation.
A working example of a CallbackHandler implementation is available from https://github.com/gatein/gatein-wsrp/tree/master/examples/wss-callback
30.6.3. Configuring the Keystores
Note
In this example we are making it a bit easier by specifying the same keystore password for both the producer and consumer, as they can use the same password callback class.
- Generate the producer's private encryption keys
keytool -genkey -alias producerAlias -keypass wsrpAliasPassword -keystore producer.jks -storepass keyStorePassword -dname "cn=producerAlias" -keyalg RSA
- Export the producer's public key
keytool -export -alias producerAlias -file producerkey.rsa -keystore producer.jks -storepass keyStorePassword
- Generate the consumer's private encryption keys
keytool -genkey -alias consumerAlias -keypass wsrpAliasPassword -keystore consumer.jks -storepass keyStorePassword -dname "cn=consumerAlias" -keyalg RSA
- Export the consumer's public key
keytool -export -alias consumerAlias -file consumerkey.rsa -keystore consumer.jks -storepass keyStorePassword
- Import the consumer's public key into the producer's keystore
keytool -import -alias consumerAlias  -file consumerkey.rsa -keystore producer.jks -storepass keyStorePassword -noprompt
- Import the producer's public key into the consumer's keystore
keytool -import -alias producerAlias  -file producerkey.rsa -keystore consumer.jks -storepass keyStorePassword -noprompt
- Copy the
producer.jksfile to thestandalone/configuration/gatein/wsrp/cxf/ws-security/producerdirectory on the producer - Copy the
consumer.jksfile to thestandalone/configuration/gatein/wsrp/cxf/ws-security/consumerdirectory on the consumer
30.6.4. Configuring the Producer
- Create
standalone/configuration/gatein/wsrp/cxf/ws-security/producer/WSS4JInInterceptor.propertieswith the following content. This will configure the incoming message between the producer and the consumeraction=Signature Encrypt Timestamp signaturePropFile=producer-security.properties decryptionPropFile=producer-security.properties passwordCallbackClass=test.TestCallbackHandler
- Create
standalone/configuration/gatein/wsrp/cxf/ws-security/producer/WSS4JOutInterceptor.propertieswith the following content. This will configure the outgoing message between the producer and the consumeraction=Signature Encrypt Timestamp signaturePropFile=producer-security.properties encryptionPropFile=producer-security.properties passwordCallbackClass=test.TestCallbackHandler user=producerAlias encryptionUser=consumerAlias signatureUser=producerAlias
- Create
standalone/configuration/gatein/wsrp/cxf/ws-security/producer/producer-security.propertieswith the following content: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=keyStorePassword org.apache.ws.security.crypto.merlin.file=producer.jks
- The
passwordCallbackClassproperty in these configuration files needs to match the fully qualified name of your CallbackHandler implementation class. In our case, it istest.TestCallbackHandler.
30.6.5. Configuring the Consumer
- Create standalone/
configuration/gatein/wsrp/cxf/ws-security/consumer/WSS4JOutInterceptor.propertieswith the following content. This will configure the outgoing message between the consumer and the produceraction=Signature Encrypt Timestamp signaturePropFile=consumer-security.properties encryptionPropFile=consumer-security.properties passwordCallbackClass=test.TestCallbackHandler user=consumerAlias encryptionUser=producerAlias signatureUser=consumerAlias
- Create standalone/
configuration/gatein/wsrp/cxf/ws-security/consumer/WSS4JInInterceptor.propertieswith the following content. This will configure the incoming message between the consumer and the produceraction=Signature Encrypt Timestamp signaturePropFile=consumer-security.properties decryptionPropFile=consumer-security.properties passwordCallbackClass=test.TestCallbackHandler
- Create standalone/configuration/gatein/wsrp/cxf/ws-security/consumer/consumer-security.properties with the following content:
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=keyStorePassword org.apache.ws.security.crypto.merlin.file=consumer.jks
- The
passwordCallbackClassproperty in these configuration files needs to match the fully qualified name of your CallbackHandler implementation class. In our case, it istest.TestCallbackHandler.
30.7. Configuring WSRP using User name Token, Encryption and Signing with User Propagation
30.7.1. Sample Configuration using User name Token, Encryption and Signing with User Propagation
This section outline how to configure the producer and consumer to encrypt and sign the soap message as well as use user propagation between the producer and consumer.
30.7.2. Configure the Producer
Follow the steps outlined in the Section 30.6.1, “Sample Configuration for securing the Endpoints using Encryption and Signing” but make the following changes:
- rename the
WSS4JInInterceptor.propertiesfile toGTNSubjectCreatingInterceptor.properties - set the action property in
GTNSubjectCreatingInterceptor.propertiesas:action= gtn.UsernameToken.ifAvailable Signature Encrypt Timestamp
- set the passwordType in
GTNSubjectCreatingInterceptor.propertiesas:passwordType=PasswordText
30.7.3. Configure the Consumer
Follow the steps outlined in the Section 30.6.1, “Sample Configuration for securing the Endpoints using Encryption and Signing” section but make the following changes:
- set the action property in
WSS4JOutInterceptor.propertiesas:action=gtn.UsernameToken.ifCurrentUserAuthenticated Signature Encrypt Timestamp
- set the user in the
WSS4JOutInterceptor.propertiesas:user=gtn.current.user
- set the passwordType in the
WSS4JOutInterceptor.propertiesas:passwordType=PasswordText
