Configure Web Services Security with WebSphere: Part 1, HTTPS, .NET, and UsernameToken

In Part 1 of this two-part tutorial, you'll learn how to use IBM® WebSphere® Studio Application Developer V5.1.2 (hereafter called Application Developer) to secure a Web service using transport-level security (HTTPS), and how to access it from Java™ 2 Extended Edition (J2EE), Java 2 Standard Edition (J2SE) and .Net clients. We'll then add a UsernameToken, digital signatures and encryption in a Web services security header and invoke them from a J2EE client.

Tony Cowan (ttcowan@us.ibm.com), Senior IT Specialist, IBM

Tony Cowan photoTony Cowan is a senior certified IT specialist with the IBM Software Services for WebSphere (ISSW) team. He has been consulting in distributed system development for over 12 years and has lead IBM teams on many projects with Fortune 1000 companies. Tony currently focuses on teaching Web services and Web services security to IBM consultants and customers. A frequent speaker at technical events, one of Tony's primary objectives at IBM is to bring real customer requirements to the IBM development teams to assist in aligning IBM's products with real world needs.



13 April 2005

Overview of the sample scenario

In this tutorial, we'll learn how to configure security for Web services in Application Developer and Application Server. We'll configure both transport-level and Web services security. Our sample scenario consists of three clients and a server as shown in Figure 1.

Figure 1. Sample scenario
Figure 1. Sample scenario

First, you'll need to create the following Java projects in Application Developer:

  • EchoService - An enterprise application that contains an EJB module (EchoServiceEJB) that contains the implementation of the sample service (EchoService) and a Web module (EchoServiceWeb) that hosts the service HTTP endpoint and forwards requests to the implementation in the EJB module.
  • EchoServiceClient - An enterprise application that contains a Web module (EchoServiceClientWeb) that holds a servlet (TestServlet) that is a client of the EchoService.
  • EchoServiceJ2SEClient - A standalone Java application project that holds a Java application (TestClient) that is a client of the EchoService.
  • EchoServiceClient.exe - A .Net EchoService client built on Microsoft™ Windows™ 2000 with .Net framework Version 1.1 and Microsoft Web Services Enhancements V2.0.

PKI Keys and Certificates

We'll use PKI keys and certificates at two levels. First, we'll secure the HTTP transport with SSL, and certificates will be needed for that. Second, the clients will be interacting with the server using Web services and Web services security containing XML Signature and XML Encryption elements, so certificates will be required for that, as well.

Transport Security (SSL)

Each of the three clients in the sample scenario will use SSL transport security. The servlet and Java 2 Standard Edition clients will use mutually authenticated SSL, while the .Net client will use only server authentication.

Web Services Security

Only the servlet-based client, TestServlet, is capable of Web services security. We'll configure XML Digital Signatures, XML Encryption and UsernameTokens for that client.


Prerequisites

In order to complete the tutorial, you will need:

  • Application Developer V5.1.2 with the V5.1 WebSphere Test Environment.
  • If you want to use the .Net client supplied as part of this tutorial, you'll also need to a Windows machine (2000 or XP) with the .Net framework V1.1 installed.

The following knowledge is assumed:

  • Familiarity with using Application Developer V5.1.2 to build Web services.
  • An understanding of security concepts and terminology.
  • Familiarity with using Application Developer to secure a Web application.

Get started

The Application Developer V5.1.2 project interchange file needed to create all of the projects used in this tutorial is called WSS5.1.zip, and is included in the wssecurity1.zip file provided in the Downloads section.

  1. Start Application Developer by selecting Start => Programs => WebSphere Studio => Application Developer.
  2. Create a new workspace by appending the name L10 to the default name.
  3. Import the EchoService and clients into the workspace as follows:
    1. Select File => Import => Project Interchange.
    2. Browse to the /WTE2004/WSSecurity folder.
    3. Select WTE2004WSLabs.zip
  4. Generate the EJB Deploy and RMIC code as follows:
    1. Select the EchoServiceEJB project under EJB Modules.
    2. Right-click on the project and select Generate => Deploy and RMIC Code.
    3. Select EchoService, and click Finish.
  5. Verify that the test server starts without error by doing the following:
    1. Open the Server perspective.
    2. Select the Servers tab.
    3. Right-click on the WebSphere v5.1 Test Environment server, and select Start. If the application server starts successfully, you should see the following in the console window:

      Click to see code listing

      *** Starting the server ***
      ************ Start Display Current Environment ************
      WebSphere Platform 5.1 [BASE 5.1.0.3 cf30412.02] [JDK 1.4.1 b0344.02]  running with 
      	process name localhost\localhost\server1 and process id 3988
      Host Operating System is Windows XP, version 5.1
      Java version = J2RE 1.4.1 IBM Windows 32 build cn1411-20031011 (JIT enabled: jitc), 
      	Java Compiler = jitc, Java VM name = Classic VM
      was.install.root = d:\IBM\WebSphere Studio\Application Developer\v5.1.2\runtimes\base_v51
      user.install.root = d:\IBM\WebSphere Studio\Application Developer\v5.1.2\runtimes\base_v51
      Java Home = d:\IBM\WebSphere Studio\Application Developer\v5.1.2\runtimes\base_v51\java\jre
      ws.ext.dirs = d:\IBM\WebSphere Studio\Application 
      		.......
      
      [10/3/04 12:48:35:350 EDT] 3cc0110b ApplicationMg A WSVR0200I: Starting application: EchoService
      [10/3/04 12:48:35:370 EDT] 3cc0110b EJBContainerI I WSVR0207I: Preparing to start EJB jar: EchoServiceEJB.jar
      [10/3/04 12:48:37:833 EDT] 3cc0110b EJBContainerI I WSVR0037I: Starting EJB jar: EchoServiceEJB.jar
      [10/3/04 12:48:37:954 EDT] 3cc0110b WebContainer  A SRVE0169I: Loading Web Module: EchoServiceWeb.
      [10/3/04 12:48:37:994 EDT] 3cc0110b WebGroup      
      	I SRVE0180I: [EchoServiceWeb] [/EchoServiceWeb] [Servlet.LOG]: JSP 1.2 Processor: init
      [10/3/04 12:48:38:074 EDT] 3cc0110b WebGroup      
      	I SRVE0180I: [EchoServiceWeb] [/EchoServiceWeb] [Servlet.LOG]: SimpleFileServlet: init
      [10/3/04 12:48:38:084 EDT] 3cc0110b WebGroup      
      	I SRVE0180I: [EchoServiceWeb] [/EchoServiceWeb] [Servlet.LOG]: InvokerServlet: init
      [10/3/04 12:48:38:915 EDT] 3cc0110b ApplicationMg A WSVR0221I: Application started: EchoService
      [10/3/04 12:48:38:915 EDT] 3cc0110b ApplicationMg A WSVR0200I: Starting application: EchoServiceClient
      [10/3/04 12:48:39:145 EDT] 3cc0110b WebContainer  A SRVE0169I: Loading Web Module: EchoServiceClientWeb.
      [10/3/04 12:48:39:195 EDT] 3cc0110b WebGroup      
      	I SRVE0180I: [EchoServiceClientWeb] [/EchoServiceClientWeb] [Servlet.LOG]: JSP 1.2 Processor: init
      [10/3/04 12:48:39:205 EDT] 3cc0110b WebGroup      
      	I SRVE0180I: [EchoServiceClientWeb] [/EchoServiceClientWeb] [Servlet.LOG]: SimpleFileServlet: init
      [10/3/04 12:48:39:215 EDT] 3cc0110b WebGroup      
      	I SRVE0180I: [EchoServiceClientWeb] [/EchoServiceClientWeb] [Servlet.LOG]: InvokerServlet: init
      [10/3/04 12:48:39:226 EDT] 3cc0110b ApplicationMg A WSVR0221I: Application started: EchoServiceClient
      [10/3/04 12:48:39:296 EDT] 3cc0110b HttpTransport A SRVE0171I: Transport http is listening on port 9,080.
      [10/3/04 12:48:40:668 EDT] 3cc0110b HttpTransport A SRVE0171I: Transport https is listening on port 9,443.
      [10/3/04 12:48:40:708 EDT] 3cc0110b RMIConnectorC A ADMC0026I: RMI Connector available at port 2809
      [10/3/04 12:48:40:738 EDT] 3cc0110b WsServer      A WSVR0001I: Server server1 open for e-business

Create the key stores

This section describes the steps required to create key stores and keys for use with Application Server for testing purposes. It doesn't cover the practice of issuing certificate requests, as would be normal in a production environment.

Application Server provides two tools for manipulating key stores:

  • iKeyman provides a graphical interface for working with key stores, and may be more appropriate for new users. One limitation of iKeyman is that it does not allow users to specify per-key passwords. It sets the key password to be the same as the key store password for all keys in the store.
  • keytool is shipped with the Java Development Kit (JDK) and provides a command line interface. For most applications, this is the preferred option because it can be scripted.

Because of its greater flexibility in allowing key passwords to be configured independently of the key store password, and because it can be scripted, we'll use keytool to create the keys in this tutorial.

Note that while both tools allow the user to generate self-signed certificates, neither tool allows the user to sign a certificate. The ability to sign a certificate with some trusted certificate authority key is required of most sophisticated PKI installations, which suggests that any organization deploying PKI technology should be investigating a mature tool for this purpose. The tools shipped with Application Server are appropriate for small installations and for testing purposes.

Map out your key requirements

This often overlooked step can help avoid confusion and frustration that often culminate in an expensive visit by a security specialist. Take a few minutes to draw out logically the systems that will be communicating and indicate what keys they will need and in what key stores those keys will be stored. Figure 2 shows one possible layout for the key stores. In this figure, the Echo Service is hosted in an Application Server.

Figure 2. Sample key store layout
Figure 2. Sample key store layout

Generate keys for SSL/TLS

When generating keys for use with transport security, two issues arise. First, the common name (CN) component of the distinguished name (DN) in the certificate issued to the server should be the domain name of the server. Second, if client certificates are to be used, the DN in the client certificate may have to map to a real user in a user registry used by the server. Application Server can be configured to check only that the client certificate was issued by a trusted certificate authority, but might also be configured to establish a security context based on the DN in the client certificate. In the latter case, the client certificate must contain a valid user DN for the Application Server realm.

For mutual SSL, we'll need both client and server keys.

  • Client-side considerations: We won't use the client certificate used to establish the SSL session for the purpose of establishing an Application Server security context, so we don't need to be concerned with issuing a client certificate that has a DN that matches a DN in the Application Server user registry. However, we'll need to configure the client to trust the certificate authority (CA) that signed the server's public key certificate. In our case, because the server's certificate will be self-signed, we need to configure the server's public key certificate as a trusted signer for the client.
  • Server-side considerations: We'll be configuring the server to expect a client certificate issued by a trusted CA. Because our client certificate will be self-signed, we'll need to configure the client's public key certificate as a trusted signer for the server. Also, as stated above, by convention, clients are programmed to expect that the certificate used to identify the server (the certificate the server presents to the client when the SSL session is established) will have a CN that is the domain name of the host the client thinks it is communicating with. That means that when a client tries to establish an SSL connection with, for example, https://www.mydomain.com/, the client expects the CN in the certificate presented by the server to the client will be www.mydomain.com. This is a slight simplification, and more complicated scenarios are possible, but it represents the core of the issue. We will, therefore, need to decide what URL the client will use to contact the server and create a certificate for the server with its CN set accordingly. To simplify our scenario, we'll be running all of our clients and our server on the same machine, so we can choose to use a host name of localhost in the URL used by the client to connect with the server. This means, therefore, that our server certificate's CN should be set to localhost.

By convention, key stores are separated into those that contain private keys, and those that contain public keys. The latter are always wrapped in public key certificates. We'll follow that convention here by creating two key stores for each of the clients and the server.

For a detailed explanation of the command line options used below, see the keytool User Guide.

We're generating these keys with the expectation that we'll be using them with Application Server. When creating an SSL configuration for Application Server, you'll notice that there is no field to specify a key alias or key password. What you can infer from this is that the key store used to hold a private key for use with SSL should contain only one private key (it can contain other public key certificates). You can also infer that the key password must be set to the key store password.

The following steps describe how to create the keys used in this exercise. You may exercise these one at a time as documented in the subsequent section or use the createKeyStores.cmd command file provided in the wssecurity1.zip file.

Set up the keytool

  1. Open a command prompt and go to the directory c:\WSSLabOne.
  2. Add the directory containing keytool to your path by typing the command:
    set PATH=<WSAD_Install_Root>\runtimes\base_v51\java\jre\bin\;%PATH%

    where <WSAD_Install_Root> is the Application Server installation directory. For example:
    d:\IBM\WebSphere Studio\Application Developer\V5.1.2

Create key pairs and certificates for the J2SE and J2EE clients

  1. To create the key pair and self-signed public key certificate to represent the J2SE and J2EE clients, go to a command prompt and type the following command on a single line:
    keytool -genkey -v -alias wasclient -keypass clientsslkeys -keystore clientsslkeys.jceks 
    	-storepass clientsslkeys -storetype jceks -dname "cn=wasclient, o=ibm, c=us" -keyalg "RSA"

    Upon successful completion, you'll see the following:

    Click to see code listing

    Generating 1,024 bit RSA key pair and self-signed certificate (MD5WithRSA) for: CN=wasclient, O=ibm, C=us 
    [Saving clientsslkeys.jceks]

    You should also have a file called clientsslkeys.jceks.

    Note, if you were going to establish a security context in Application Server based on the identity in the client certificate, you would need to use a DN in the keytool command that existed in the user registry used by the Application Server hosting the service. To do this, you would need to determine the DN of the user you wanted the client to represent, then place that DN in quotes after the -dname option.

  2. To export the client public key certificate so that it can be imported into the server's trust store, type the following command:
    keytool -export -v -alias wasclient -file wasclient.cert -rfc -keystore clientsslkeys.jceks 
    	-storepass clientsslkeys -storetype jceks

    Upon successful completion of this command, you'll see the following:

    Certificate stored in file <wasclient.cert>

    Now you'll have a second file called wasclient.cert.

Create a key pair and certificates for the server

  1. Type the following command on a single line to create a key pair and self-signed public key certificate to represent the Application Server:

    Click to see code listing

    keytool -genkey -v -alias wasserver -keypass serversslkeys -keystore serversslkeys.jceks -storepass serversslkeys 
    	-storetype jceks -dname "cn=localhost, o=ibm, c=us" -keyalg "RSA"

    Upon successful completion, you'll see the following:

    Generating 1,024 bit RSA key pair and self-signed certificate (MD5WithRSA)
            for: CN=localhost, O=ibm, C=us
    [Saving serversslkeys.jceks]

    You should have a file called serversslkeys.jceks.

    Note, if you were going to use a host name other than localhost in the URL to access the server, you would need to modify the DN above to reflect that. To do that, you would determine the host name of the server you wanted the client to use in the URL, and then place that string in the cn= section of the DN in quotes after the -dname option in the keytool command. The configuration above will work for URLs like this: http://localhost/somepath.

  2. Export the server's public key certificate so that it can be imported into the client's trust store, by typing the following command:
    keytool -export -v -alias wasserver -file wasserver.cert -rfc -keystore serversslkeys.jceks 
    	-storepass serversslkeys -storetype jceks

    Upon successful completion of this command you will see the following:

    Certificate stored in file <wasserver.cert>

    You'll now have a file called wasserver.cert.

Now that we've created the keystores for the client and sever, we need to create the trust stores for the client and server to establish the trust domain. We need to create a trust store for the client with the server's public key certificate in it. You must have already created the server key store and exported the server's public key certificate using the commands in the server section above before creating the client trust store.

  1. Create the trust store for the client with the server's public key certificate by executing the following command:
    keytool -import -v -noprompt -alias wasserver -file wasserver.cert -keystore 
    	clientssltrusts.jceks -storepass clientssltrusts -storetype jceks

    Upon completion, you'll see the following:

    Certificate was added to keystore
    [Saving clientssltrusts.jceks]

    The file clientssltsrts.jceks has been created.

  2. Create the trust store for the server with the client's public key certificate by executing the following command:
    keytool -import -v -noprompt -alias wasclient -file wasclient.cert -keystore serverssltrusts.jceks 
    	-storepass serverssltrusts -storetype jceks

    Upon completion, you'll see the following:

    Certificate was added to keystore
    [Saving serverssltrusts.jceks]

    The file serverssltsrts.jceks has been created.

We now have all the files we need to configure the SSL connections shown in our sample scenarios. We can use the wasserver.cert file to configure the Windows environment for the .Net client. Next we need to create the keys and certificates for the Web services security signatures and encryption.

Generate keys for Web services security

In our implementation we have a client and a service: EchoServiceClient and EchoService. To allow for digital signatures using PKI technology, the signing party (EchoServiceClient) must have access to a private key that identifies it to the signature verifier (EchoService). The signature verifier must have access to the public key certificate that contains the public key associated with the private key used to produce the signature.

For encryption using PKI technology, the encrypting party must have access to the public key certificate that contains the public key of the party for whom the message is encrypted; that is, the decrypting party. The decrypting party must have access to the private key associated with the public key used to encrypt the message.

In our scenario, we'll sign and encrypt both requests to and from the service. In practice, our configuration will be almost identical to the one required for the SSL configuration, with the exception that there is no expectation on the part of the client that the CN in the service's DN match the host name in the URL of the service. Because Application Server V5.1 supports only J2EE clients, we will not be considering the J2SE client.

Following convention, we'll separate our key stores into those that contain private keys, and those that contain public keys (the latter are always wrapped in a public key certificates). We'll end up with two key stores each for the client and the service. For a detailed explanation of the command line options used below, see the keytool User Guide.

Create keys for the EchoService client

  1. Type the following command on a single line to create a key pair and self-signed public key certificate to represent the J2EE-based EchoService client:

    Click to see code listing

    keytool -genkey -v -alias echoserviceclient -keypass echoserviceclient -keystore echoserviceclientkeys.jceks 
    	-storepass echoserviceclientkeys -storetype jceks -dname "cn=EchoServiceClient, o=ibm, c=us" -keyalg "RSA"

    Upon completion, you'll see the following:

    Generating 1,024 bit RSA key pair and self-signed certificate (MD5WithRSA)
            for: CN=EchoServiceClient, O=ibm, C=us
    [Saving echoserviceclientkeys.jceks]

    If you were going to establish a security context in Application Server based on the identity in the client certificate (by passing the client's certificate in the Web services security header), you would need to use a DN in the keytool command that existed in the user registry used by the Application Server hosting the service. To do that, you would determine the DN of the user you wanted the client to represent, then place that DN in quotes after the -dname option.

  2. Export the client public key certificate so it can be imported into the service's store of trusted client certificates by typing the following command:

    Click to see code listing

    keytool -export -v -rfc -alias echoserviceclient -file echoserviceclient.cert -keystore echoserviceclientkeys.jceks 
    	-storepass echoserviceclientkeys -storetype jceks

    Upon completion, you'll see the following:

    Certificate stored in file <echoserviceclient.cert>

Create keys for the EchoService

  1. Type the following command on a single line to create a key pair and self signed public key certificate to represent the EchoService:
    keytool -genkey -v -alias echoservice -keypass echoservice -keystore echoservicekeys.jceks 
    	-storepass echoservicekeys -storetype jceks -dname "cn=EchoService, o=ibm, c=us" -keyalg "RSA"

    You'll see the following:

    Generating 1,024 bit RSA key pair and self-signed certificate (MD5WithRSA)
            for: CN=EchoService, O=ibm, C=us
    [Saving echoservicekeys.jceks]
  2. Export the service's public key certificate so it can be imported into the client's store by typing the following command:
    keytool -export -v -rfc -alias echoservice -file echoservice.cert -keystore echoservicekeys.jceks 
    	-storepass echoservicekeys -storetype jceks

    You'll see the following:

    Certificate stored in file <echoservice.cert>

Create the trust stores

Now that we have created the keystores for the EchoService client and EchoSevice, we need to create the trust stores for the client and service to establish the trust domain.

Create EchoClient key store

Now we need to create a key store for the client with the service's public key certificate in it, so that we can use the server's public key to verify signatures from the service and to encrypt messages for the service. To do this, type:

keytool -import -v -noprompt -alias echoservice -file echoservice.cert -keystore echoservicecerts.jceks 
	-storepass echoservicecerts -storetype jceks

You'll see the following:

Certificate was added to keystore
[Saving echoservicecerts.jceks]

Create EchoServer key store

We need to create a key store for the service with the client's public key certificate in it so that we can use the client's public key to verify signatures from the client and to encrypt messages for the client. To do this, type:

Click to see code listing

keytool -import -v -noprompt -alias echoserviceclient -file echoserviceclient.cert -keystore echoserviceclientcerts.jceks 
	-storepass echoserviceclientcerts -storetype jceks

You'll see the following:

Certificate was added to keystore
[Saving echoservicclientecerts.jceks]

We have now built all of the key store files necessary to configure our sample scenarios. Scripts are provided in the Download section that accomplishes all of these steps. The first version works for Linux™/Unix® platforms, the second for Windows™.


Configure transport-level security

Now that the key stores are in place, we'll configure the security for the service and clients. In the examples that follow, we'll use mutual SSL to provide integrity and confidentiality to the Web service invocation. Once that's in place we'll add a UsernameToken in a Web services security header to provide authentication. As you'll see, the server side configuration for transport level security is, in fact, simply following the same configuration steps you would if you were securing any regular URL hosted by any regular Web application.

Enable Application Server Global Security

  1. Double-click on the server in the server list to open up the server configuration editor.
  2. Switch to the Security tab and do the following:
    • Check the Enable security checkbox.
    • Specify wasuser as the Server ID.
    • Specify wasuser as the Server password.
    Figure 3. Enable security
    Figure 3. Enable security
  3. Save the configuration and restart the server.

Configure Enterprise Application Security

  1. In the Web perspective, select EchoServiceWeb => Web Deployment Descriptor.
  2. Click the Security tab.
  3. In the Security Roles field, click Add to add a new security role.
  4. Name the security role EntityConnectingToEchoServiceUsingSSL.
    Figure 4. Add security role
    Figure 4. Add security role
  5. Still on the Security page, switch from the Security Roles tab to the Security Constraints tab.
  6. Click Add to add a new security restraint.
  7. In the Web Resource Collections section, select the default web resource collection New Web Resource Collection, and click Edit.
  8. Edit the collection as follows:
    • Set the name to EchoService.
    • Check all the HTTP methods.
    • Add the service URL /services/EchoService (the URL in the WSDL without the Web application context root).
    • Click OK.
    Figure 5. Edit Web resource collection
    Figure 5. Edit Web resource collection
  9. In the Authorized Roles section, click Edit and add the role we just created, EntityConnectingToEchoServiceUsingSSL.
  10. In the User Data Constraint field, change the data constraint type to Confidential.
  11. Switch to the Pages tab and check the Loginsection to ensure that the Authentication Method is set to Unspecified.
    Figure 6. Login authentication method
    Figure 6. Login authentication method

    If you wanted to establish an Application Server security context based on the incoming client certificate, you would set the authentication method to Client-Cert. You would have to use a valid user DN in your certificate for that to work. When the authentication method is unspecified, it defaults to Basic, which means that Application Server will look for a user name and password in the HTTP headers.

    We will not be sending this information initially, so we must tell the Application Server that the URL we just protected should be allowed access from everyone. We do this in the enterprise application deployment descriptor, as described below.

  12. Save the configuration and close the Web application deployment descriptor editor.
  13. Select EchoService => EAR Deployment Descriptor to edit the EchoService enterprise application deployment descriptor.
  14. Switch to the Security tab and click Gather.
  15. Select the gathered role EntityConnectingToEchoServiceUsingSSL.
  16. Check Everyone under WebSphere Bindings. This effectively disables J2EE security context generation, which frees us from having to use a valid user name in the client certificate.
    Figure 7. Specify security access
    Figure 7. Specify security access
  17. Save the configuration and close the editor.

Create an SSL Configuration

When creating an SSL configuration for Application Server, you'll notice that there is no field to specify a key alias or key password. You can infer from this that:

  • The key store used to hold a private key for use with SSL should only contain one private key (it can contain other public key certificates).
  • The key password must be set to the key store password.

There are two ways to create an SSL configuration in Application Developer:

  • Enable the administrative console on the application server and then use the console to create the SSL configuration.
  • Add the SSL configuration in the application server configuration editor.

The former will provide some default information that you'll have to enter manually when using the latter. We'll discuss the first method.

  1. From the server perspective, double-click on the server in the server list to open the configuration editor.
  2. Switch to the Configuration tab.
  3. Under Server Configuration, check Enable administration console.
    Figure 8. Enable administration console
    Figure 8. Enable administration console
  4. Save the configuration and close the editor.
  5. Restart the server.
  6. Right-click on the server in the server list, and select Run administrative console. If presented with a security alert, click Yes.
  7. Log in to the administrative console using wasuser as the user ID and password.
  8. In the navigation tree, select Security => SSL to see the list of SSL configurations.
  9. Click New to create a new SSL configuration.
    Figure 9. SSL configuration
    Figure 9. SSL configuration
  10. Fill in the new SSL configuration as follows:
    • Specify an alias name that identifies it with the Application Server; for example: WASServerSSL.
    • Set the key file name to the full path in the file system to your server SSL key file; for example: <path>/serversslkeys.jceks, where <path> is the location of your key file.
    • Set the password for the key file; for example: serversslkeys.
    • Set the key store format to the store type, as appropriate. The editor calsl JCEKS types JCEK.
    • Set the trust file name to the full path in the file system of your server SSL trust file; for example <path>/serverssltrusts.jceks, where <path>> is the location of your key file.
    • Set the trust file password; such as serverssltrusts.
    • Set the trust file format; for example, JCEK.
    • Select Client authentication.
    • Click OK to save the configuration. Note that the configuration will not actually be saved until you click Save at the top of the screen, but because we'll be making more modifications to the configuration, we'll save all the changes in one go after we're finished.
    Figure 10. SSL configuration
    Figure 10. SSL configuration

Configure Web Container

Now we need to set the web container to use our new SSL configuration on an HTTPS port. From the administrative console, follow these steps:

  1. Select Servers => Application Servers.
  2. Select server1 in the server list.
  3. Under Additional Properties, select Web Container.
    Figure 10. Select Web Container
    Figure 10. Select Web Container
  4. Under Additional Properties, select HTTP Transports.
    Figure 11. Select HTTP transports
    Figure 11. Select HTTP transports

    Application Server is configured to expose applications over SSL on port 9443. You could create a new transport definition and listen on a different port here, but for now let's just modify the SSL configuration on port 9443.

  5. Check the host name associated with port 9443. The default is *, which means accept any host name.
    Figure 12. Select host name
    Figure 12. Select hostname
  6. Change the SSL configuration for this transport to use our new SSL configuration localhost/WASServerSSL. Note that the administrative console prepends localhost/ to the name you gave the SSL configuration.
    Figure 13. Specify SSL configuration
    Figure 13. Specify SSL configuration
  7. Click OK.
  8. Click the Save link at the top of the screen to save the configuration changes.
  9. Click Save to write the changes to the configuration files.

Configure Application Server-Based Client

Application Server-based clients are Web services clients that run inside an Application Server container. Examples are servlets, JSPs and EJBs. Complete the steps in the following sections to configure the Application Server based Web services client to use SSL for its connection to the service. In our sample scenario, our Application Server-based client is a servlet implemented in the EchoServiceClientWeb Web application in the com.ibm.issw Java package. We'll be making changes to the sample scenario code using Application Developer.

Change Service Endpoint

There are a couple of ways you can change the endpoint that the client will use to invoke the service. The first is to modify the generated Locator class. However, this isn't such a good strategy, because the class will be overwritten if ever the proxy is regenerated. A better approach is to call setEndpoint() on the proxy after you instantiate it.

  1. From the Java perspective, select EchoServiceClientWeb => com.ibm.issw => TestServlet.
  2. Add a line to the code after the proxy object is created to invoke setEndpoint() on it as shown below.
    Figure 14. Modify code to invoke setEndpoint()
    Figure 14. Modify code to invoke setEndpoint()
  3. To get a good starting URL to pass to setEndpoint(), open the generated Locator class and look for the private final String echoService_address.
  4. Select the address string and copy it to the clipboard.
    Figure 15. Get URL address
    Figure 15. Get URL address
  5. Switch back to the TestServlet code and paste the address into the call to setEndpoint() and make the following modifications:
    • Change the protocol to https.
    • Change the port to 9443. The line should look like this:
      proxy.setEndpoint ("https://localhost:9443/EchoServiceWeb/services/EchoService");

      as shown below:
      Figure 16. Modify TestServlet code
      Figure 16. Modify TestServlet code
  6. Save the TestServlet code.

Create an SSL Configuration

Now we need to create an SSL configuration for the client to use when communicating with the server. When creating an SSL configuration for Application Server, you'll notice that there is no field to specify a key alias or key password. What you can infer from this is that the key store used to hold a private key for use with SSL should contain only one private key (it can contain other public key certificates). You can also infer that the key password must be set to the key store password. The steps for this exercise are similar to those used for the server side, as follows:

  1. Log in to the administrative console using wasuser as the user ID and password. Note that you may already be logged in from the previous configuration of the server side.
  2. From the navigation tree, select Security => SSL to see the list of SSL configurations.
  3. Click New to create a new SSL configuration.
  4. Fill in the new SSL configuration as follows:
    • Set the alias to a name that identifies it with the Application Server; for example, WASClientSSL.
    • Set the key file name to the full path in the file system to your server SSL key file; for example, <path>/clientsslkeys.jceks, where <path> is the location of your key file.
    • Set the password for the key file; for example, clientsslkeys.
    • Set the key store format as appropriate to the store type. The editor calls JCEKS types JCEK.
    • Set the trust file name to the full path in the file system of your server SSL trust file; for example, <path>/clientssltrusts.jceks, where <path> is the location of your key file.
    • Set the trust file password; for example, clientssltrusts.
    • Set the trust file format; for example: JCEK.
    • Click OK.
    • Click Save at the top of the screen.
    • Click Save.
      Figure 17. Configure SSL
      Figure 17. Configure SSL

Configure the Web Service Deployment Descriptor

Now that we have an SSL configuration for the client, we need to tell the Application Server Web service client stub to use it when invoking the service. To do this, we'll add a reference to the SSL configuration to the Web service client deployment descriptor files.

  1. In the Web perspective, select EchoServiceClientWeb => Web Content => WEB-INF => wsdl => webservicesclient.xml.
  2. Switch to the Port Bindings tab.
  3. In the Port Qualified Name Binding Details section, enter localhost/WASClientSSL in the HTTP SSL configuration name field. Note that when the SSL configuration is added through the administrative console, localhost/ is prepended to the name you specify for the SSL configuration.
    Figure 18. Configure Web service deployment descriptor
    Figure 183. Configure Web service deployment descriptor
  4. Restart the server.
  5. You can now test your Application Server based client for connectivity to your service by invoking the TestServlet with this URL: http://localhost:9080/EchoServiceClientWeb/TestServlet.

Configure Non-Application Server-Based Client

Non-Application Server based clients are those clients that execute outside of an Application Server container. Examples are managed J2EE client applications and standalone J2SE Java applications.

Change Service Endpoint

There are a couple of ways you can change the endpoint that the client will use to invoke the service. The first is to modify the generated Locator class. However, this is'nt such a good strategy, because the class will be overwritten if the proxy is ever regenerated. A better approach is to call setEndpoint() on the proxy after you instantiate it. To do that, follow these steps:

  1. In the Java perspective, select EchoServiceJ2SEClient => com.ibm.issw => TestClient.java.
  2. Add a line to the code after the proxy object is created to invoke setEndpoint() on it.
  3. To get a good starting URL to pass to setEndpoint(), open the generated Locator class and look for the private final String echoService_address.
  4. Select the address string and copy it to the clipboard.
  5. Switch back to the TestClient code and paste the address into the call to setEndpoint() and make the following modifications:
    • Change the protocol to https.
    • Change the port to 9443.
    • The line should look like this:
      proxy.setEndpoint("https://localhost:9443/EchoServiceWeb/services/EchoService");

      as shown below:
      Figure 19. Configure service endpoint
      Figure 19. Configure service endpoint
  6. Save the TestClient code.

Add Protocol Provider

For the WebSphere Test Environment (WTE) that ships with Application Developer, you'll need to check that the provider is configured. The file to look in will be in a directory similar to:

<WSAD_INSTALL_ROOT>/runtimes/base_v51/java/jre/lib/security/java.security

Locate the security providers in the java.security file and add the following line:

security.provider.<n>=com.ibm.jsse.IBMJSSEProvider

where <n> is the next unused number.

Configure Libraries and System Properties

For J2SE clients, we use Java system properties to tell the runtime what key and trust stores to use. When running the Java client from the command line, add the system properties to the Java command as you would any other system properties you are defining. We'll run the Java client inside Application Developer. Add the following system properties to your JVM start-up command line in Application Developer by executing the following steps:

  1. Before we configure our Java application to use the correct set of libraries, we will define an environment variable in Application Developer to facilitate the process as follows:
    1. From Application Developer, select Window => Preferences.
    2. In the Preferences dialog, select Java => Classpath Variables from the left tree.
    3. Select and edit the variable WAS_50_PLUGINDIR. We want to copy the value of this variable to make creating the new one easier, so go ahead and copy the value of that variable to the clipboard.
    4. Click OK.
      Figure 20. Copy WAS_50_PLUGINDIR variable
      Figure 20. Copy WAS_50_PLUGINDIR variable
    5. Back on the Preferences dialog, click New to create the new variable.
    6. Call the new variable WAS_51_PLUGINDIR and paste the value from the clipboard. Add a 1 to the end of the path to end up with something like:
      /opt/IBM/WebSphereStudio/ApplicationDeveloper/v5.1.2/runtimes/base_v51
    7. Click OK.
  2. Now let's configure the client to use the correct java jar files at run time. To do that, follow these steps:
    1. Right-click on the EchoServiceJ2SEClient project, then select Properties from the context menu.
    2. In the Properties dialog, select Java Build Path from the left menu, then click the Libraries tab.
      Figure 21. Create new variable
      Figure 21. Create new variable
    3. Edit each of the entries that use the variable WAS_50_PLUGINDIR and change them to WAS_51_PLUGINDIR.
      Figure 22. Edit variables
      Figure 22. Edit variables
    4. Click OK to close the Properties dialog.
    5. Open the TestClient.java file and select Run => Run... from the Application Developer top menu.
    6. In the Run dialog, switch to the (x)=Arguments tab and enter the following into the VM Arguments section:
      -Djava.protocol.handler.pkgs=com.ibm.net.ssl.internal.www.protocol  
      -Djavax.net.ssl.trustStore=<path>/clientssltrusts.jceks 
      -Djavax.net.ssl.trustStorePassword=clientssltrusts  
      -Djavax.net.ssl.keyStore=<path>/clientsslkeys.jceks  
      -Djavax.net.ssl.keyStorePassword=clientsslkeys 
      -Djavax.net.ssl.keyStoreType=jceks 
      -Djavax.net.ssl.trustStoreType=jceks

      where <path> is the location of your key files, such as <C>/WTE2004/WSSecurity/L10.
      Figure 23. Specify VM arguments
      Figure 23. Specify VM arguments
    7. Click on the JRE tab and select WebSphere V5.1 JRE runtime in the JRE field.
    8. Click Apply, then Run to test your Java client.
      Figure 24. Specify JRE runtime
      Figure 24. Specify JREruntime

Configure the .Net client

Configuring a .Net component to provide a particular client side certificate when connecting to a service turns out to be a complex process. See Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication in the MSDN library for more information.

We can fairly easily configure our trust certificate in the Windows environment to allow the .Net client to trust the certificate provided by the Application Server. The first thing we need to do is change the server so that it does not expect a client-side certificate, then we'll configure the server certificate in the Windows environment for use by the client.

Modify Server Not to Expect Client Certificate

We'll use the Application Server administrative console to modify the SSL configuration of the server. You could also use the server configuration editor in Application Developer to do the same thing. Follow these steps:

  1. Log in to the administrative console with the wasuser ID and password. Note that you may be logged in already from the previous configuration work.
  2. From the left tree, select Security => SSL to see the list of SSL configurations.
  3. Select WASServerSSL configuration, then click Edit.
  4. Uncheck Client Authentication and save the configuration.
  5. Restart the server.

Add the Server Certificate to Windows

The Windows client is created for you and available as a console-based Windows executable. It will invoke the service and print out the echoed string on the console. In Windows, the transport mechanisms HTTP and HTTPS are handled by system components. These system components look for information in a certificate management registry. We can manage the Windows certificate registry using a tool called the Microsoft Management Console (MMC). You can invoke the MMC from the command line using the mmc command. Follow these steps to configure Windows for the Web service invocation over SSL:

  1. Start the MMC by clicking Run from the Windows Start menu, then type mmc for the command name.
  2. In the main window, select Console => Add/Remove Snap-in.
  3. In the Add/Remove Snap-in dialog, click Add.
  4. In the Add Standalone Snap-in dialog, select Certificates from the list, and click Add.
    Figure 25. Add certificates
    Figure 25. Add certificates
  5. In the Certificates Snap-in dialog, select Computer account, then click Next.
  6. In the Select Computer dialog, make sure that Local computer is selected and click Finish.
  7. Close the Add/Remove Snap-in dialog.
  8. In the left tree, select Certificates (Local Computer) => Trusted Root Certificates.
  9. Right-click Certificates and select All Tasks => Import.
    Figure 26. Import certificate
    Figure 26. Import certificate
  10. In the Certificate Import wizard, browse to the file containing the server certificate. In our case, this is wasserver.cert. Then click Next.
    Figure 27. Browse to server certificate
    Figure 27. Browse to server certificate
  11. Select Automatically select the certificate store based on the type of certificate, and click Next.
  12. Click Next on the next page, then click Finish.
  13. Answer Yes when prompted.

That's it for importing the certificate. You can now run the .Net client to access your echo service as follows:

  1. Open a command window.
  2. Change to the <drive>:/WTE2004/WSSecurity/L10 directory.
  3. Run WTE2004Client.exe.

Configure User Name Tokens

This section discusses the steps required to configure the web services security (WSS) infrastructure to pass a UsernameToken in the WSS header. It describes the steps required in Application Developer, although they are almost identical to the steps required if you use the ATK supplied with the Application Server runtime. We describe how to configure Application Server to pass a UsernameToken in the WSS header between the servlet client and the Echo Service.

Configure the Service Side

Follow these steps to configure the service side:

  1. In the Web perspective, click EchoServiceEJB => ejbModule => META-INF => wsdl => webservices.xml.
  2. Switch to the Security Extensions tab.
  3. Open the Login Config section.
  4. Click Add and select BasicAuth from the drop-down list.
    Figure 28. Configure server login authentication
    Figure 28. Configure server login authentication
  5. In the Add Authentication Method dialog, check both Nonce boxes, then click OK. Nonce is required to prevent replay attacks.
    Figure 29. Add authentication method
    Figure 29. Add authentication method
  6. Switch to the Binding Configurations tab and click Add in the Login Mapping section.
  7. In the Login Mapping dialog, do the following:
    1. Specify BasicAuth for the Authentication method.
    2. Enter a configuration name of WSLogin (case sensitive).
    3. Set the Callback handler to com.ibm.wsspi.wssecurity.auth.callback.WSCallbackHandlerFactoryImpl.
    4. Leave all other values as their defaults.
    5. Click OK.
    Figure 30. Configure server login mapping
    Figure 30. Configure server login mapping
  8. Save the configuration, then select EchoService => Restart Project.

Configure the Client Side

Follow these steps to configure the client side:

  1. In the Web perspective, click EchoServiceClientWeb => Web Content => WEB-INF => wsdl > webservicesclient.xml.
  2. Switch to the Security Extensions tab.
  3. In the Login Config section, select BasicAuth from the drop-down list in the Authentication method field, and check both Nonce boxes.
    Figure 31. Configure client login authentication
    Figure 31. Configure client login authentication
  4. Switch to the Port Binding tab and click Enable in the Login Binding section.
  5. In the Login Binding dialog, do the following:
    1. Select BasicAuth for the Authentication method.
    2. Set the Callback handler to com.ibm.wsspi.wssecurity.auth.callback.NonPromptCallbackHandler from the drop-down list.
    3. Enter the user ID and password.
    4. Click OK.
      Figure 32. Configure client login binding
      Figure 32. Configure client binding
  6. That's all we need to do to to send a statically configured UsernameToken. Test the client.by invoking the TestServlet with this URL: http://localhost:9080/EchoServiceClientWeb/TestServlet.

Download

DescriptionNameSize
sample .NET client, scripts, project filewssecurity1.zip  ( HTTP | FTP )62 KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, SOA and web services
ArticleID=85697
ArticleTitle=Configure Web Services Security with WebSphere: Part 1, HTTPS, .NET, and UsernameToken
publish-date=04132005