Wednesday, December 26, 2012

Securing Web services at the message level



We are going to configure Web service message-level security of Java API for XML Web Services 2.1 (JAX-WS) running on WebSphere Application Server 7 using the Rational Application Developer 7.5/8.0 integrated development environment (IDE). To achieve that objective, we will perform the following tasks:
  • How to create a JAX-WS service provider
  • How to create a standalone JAX-WS client.
  • How to monitor the SOAP messages using the TCP/IP Monitor.
  • How to customize a WS-Security policy set in the WebSphere Application Server Administration Console.
  • How to customize a policy set binding in the Administration Console.
  • How to export policy sets and bindings from the Administration Console.
  • How to generate X509 asymmetric keys and use them with your customized policy set bindings.
  • How to import policy sets and bindings into the Rational Application Developer IDE.
  • How to attach policy sets to Web service provider and servers using the Rational Application Developer IDE.
  • How to create TestClient code using Web Services Security APIs
  • How to use the UsernameToken (UNT) profile to add credentials to the SOAP header.
  • How to use the UNT to authenticate against the WebSphere Application Server user repository.
 


1.     Prerequisites

a)      Rational Application Developer for WebSphere Software V7.5 or V8.0 - Sample attached are developed in RAD v8.0
b)      WebSphere Application Server V7.0 - Steps captured in this document are taken from V7.0 however these steps can also be performed in V6.0/6.1 with Web Service Feature pack
c)       Web Service Feature Pack - Make sure you can see the following option when you login into Application Server Console.

If this highlighted option is not available then you need to install a Web Service feature pack onto the product using the feature pack installer. That is a separate task, different than installing a fix pack using the UpdateInstaller. If required after a feature pack is installed, you can then install the fix pack for that feature pack. Once installed a profile must be created and enabled with the feature pack functionality. The deployment manager and application server profiles are the only profiles that can be created and enabled with the feature pack. An existing stand-alone deployment manager profile can be augmented later with the feature pack, but is the only profile type which can be augmented after creation.


2.     Creating and consuming JAX-WS Web services

a)    Creating a JAX-WS Service Provider

                Use a dynamic Web project to contain the Web service. Start by creating a dynamic Web project and a plain old Java object (POJO) for your service provider as shown in the following steps :
1.       Start Rational Application Developer. Click File > New > Dynamic Web Project, then enter HelloWorldProject as the project name


2.       Accept the defaults for the other fields, then click the Finish button. Choose No if prompted to change to the Web perspective. For this tutorial, you will use the Java EE perspective.
3.       Select the HelloWorldProject project in the project explorer view. Right-click and select New > Class, which brings up a Java Class wizard. Enter com.sample for the package name and HelloWorldProvider as the class name , and click the Finish button.

4.       Add following method in this class to expose that as Web Service operation
package com.sample;
public class HelloWorldProvider {
                public String sayHello(String msg) {
                    return "Hello " + msg;
                  }
}
5.       Right click on HelloWorldProvider class and chose 'Web Services'>'Create Web Service'
Choose options as shown below

Click on Next button and select 'Generate Web Service Deployment Descriptor' as show below and then click on Finish button.


6.       This will create a delegator class HelloWorldProviderDelegate. Now we need to add @Resource WebServiceContext variable in this class. This line allows the JAX-WS runtime to inject the Web service context and enables you to access the JEE principal from the context. However, in order for this code to actually return the correct principal in Application Server, you must configure the Caller in the service provider binding; otherwise, you may get a result of "Principal: /UNAUTHENTICATED*quot;. Configuration of caller is covered in later section of 'Policy Set'.

Copy the below code into the HelloWorldProviderDelegate.java file and save the file.

package com.sample;
import javax.annotation.Resource;
import javax.xml.ws.WebServiceContext;
@javax.jws.WebService (targetNamespace="http://sample.com/", serviceName="HelloWorldProviderService", portName="HelloWorldProviderPort")
public class HelloWorldProviderDelegate{
                @Resource WebServiceContext wsCtx;
    com.sample.HelloWorldProvider _helloWorldProvider = null;
    public String sayHello(String msg) {
                System.out.println("[provider] received " + msg);
        System.out.println("[provider] user = " + wsCtx.getUserPrincipal());
        return _helloWorldProvider.sayHello(msg);
    }
    public HelloWorldProviderDelegate() {
        _helloWorldProvider = new com.sample.HelloWorldProvider(); }

}
Note - You can use Principle object to fetch group details from LDAP for restricting who can actually execute particular operation.

b)    Creating a JAX-WS service consumer

Rational Application Developer provides a wizard for generating a client from a JAX-WS Web service. You can use Dynamic web project as your service consumer. Therefore, you begin by creating a simple Dynamic Web Project that will contain your JAX-WS client proxy as well as your client code (jsp) that uses the generated client proxy to call WS Operation.
1.       Using Rational Application Developer, select File > New > Dynamic Web Project wizard.
2.       In the Dynamic Web Project wizard, enter HelloWorldConsumer as the project name, HelloWorldConsumerEAR as Ear project name, click Finish as shown below. If prompted to switch to the Java perspective, choose No to stay in the Java EE perspective.

3.       Expand the Services folder of the HelloWorldProject Web project. Right-click the HelloWorldProviderService service and choose Generate > Client
4.       Ensure the Web service runtime value in the configuration section is set to IBM WebSphere JAX-WS, Java Proxy is selected as the client type, Client Project as HelloWorldConsumer and Client EAR project as HelloWorldConsumerEAR

5.       Click the Next button and enter com.sample as the target package of the Web service client. Ensure the Generate portable client checkbox is selected. 

6.       Click the Finish button to generate the client proxy code
7.       Rational Application Developer uses the WSDL of the service provider to auto-generate Java classes that can invoke the service provider Web service. Figure below shows the classes that get generated. Using the generated proxy classes, we do not have to worry about SOAP message building, XML parsing, or any other low-level programming constructs – the generated classes do this. All we need to do is instantiate the client proxy and invoke methods we want to be sent to the Web service. Therefore, next we will create a simple JSP test client that instantiates the generated client proxy in order to invoke the service provider.

c)     Create a JSP test client

1.       Right-click the HelloWorldConsumer>WebContent folder and choose New > Web Page
2.       Enter ClientTest.jsp as file name and then click on Finish button

3.       Copy the following code into the ClientTest.jsp file and save the file.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1" import="java.util.Map,javax.xml.ws.BindingProvider,com.sample.*,com.ibm.websphere.wssecurity.wssapi.*,com.ibm.websphere.wssecurity.wssapi.encryption.WSSEncryption, com.ibm.websphere.wssecurity.wssapi.signature.WSSSignature, com.ibm.websphere.wssecurity.wssapi.token.*, com.ibm.websphere.wssecurity.callbackhandler.*"%>
<html>
<head>
<title>ClientTest</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="GENERATOR"
                content="Rational® Application Developer for WebSphere® Software">
</head>
<body>
<%
try {
                                HelloWorldProviderService srv = new HelloWorldProviderService();
                                HelloWorldProviderDelegate port = srv.getHelloWorldProviderPort();   
                                String resp = port.sayHello("World");
                                out.println("[response] " + resp);
                                } catch (Exception e) {
                                                e.printStackTrace();
                                }
 %>
</body>
</html>
Note - You may need to set following jar 'AppServer\runtimes\ com.ibm.jaxws.thinclient_7.0.0.jar ' in 'java build path' of project ' HelloWorldConsumer ' if this jsp is throwing any compilation error relates javax-ws, securities  classes not found.

d)    Test and verify the consumer and provider

                After you have the server-side and client-side up and running, it is generally a good idea to test and verify things. Rational Application Developer provides a TCP/IP Monitor view to display the SOAP message as it is transferred from the client to the server and back. To use this view, we need to configure the TCP/IP Monitor to listen on an unused TCP/IP port, and then update your client proxy code to point to this TCP/IP port. The following section demonstrates how to do this.
1.       In Rational Application Developer, select Window > Show View > Other. Then locate the TCP/IP Monitor view in the Debug folder and click OK.
2.       Right-click in the first entry box and choose Properties as shown below

3.       Click the Add button to configure a new monitor to intercept the Web service request and response in order to display the SOAP message.
4.       Enter an unused TCP port for the Local monitoring port field. (e.g. 9081)
5.       Enter localhost for the Host Name field.
6.       Enter the TCP port for the Web service provider (check the WSDL in the HelloWorldConsumer project). (e.g. 10039). You should have values similar to figure below

7.       Click the OK button.
8.       Now select your newly defined TCP/IP Monitor and click the Start button as shown below


Now that the TCP/IP Monitor is running and listening for Web service calls, you need to change your client proxy to connect to the listening port of the TCP/IP monitor instead of connecting directly to the service provider. You can accomplish this by changing the port number in the WSDL that was saved locally to the client project as a result of clicking the Generate portable client checkbox in step above ' 2.b.5'.
9.       Right-click the HelloWorldProviderService.wsdl file located in the HelloWorldConsumer project under the WebContent >WEB-INF > wsdl folder path and choose Open With > WSDL Editor.
10.   Change the port number to match the TCP/IP Monitor listening port (e.g. 9081) as shown in Figure below, then save and close the WSDL file.

11.   Right-click the ClientTest.jsp file and choose Run As > Run On Server. The results should appear in the TCP/IP Monitor view as shown in below

At this point, you have developed a JAX-WS Web service provider (i.e. server-side) and a JAX-WS Web service consumer (i.e. client-side) and demonstrated the results of the consumer invoking the provider. In the next section, we will configure the policy sets to add message-level security to HelloWorld example, and once again view the results in the TCP/IP Monitor view to verify that the SOAP message is being passed securely.

3.     Policy sets

Policy sets provide a declarative way to define qualities of service (QoS) for Web services. This simplifies the management of multiple Web services as policy sets can be reused across them. Different policy set terminology :
Policy – A policy describes a configuration that defines qualities of service (QoS) for Web services. Examples include WS-Security and WS-Addressing.
 Policy sets – A policy set is a collection of policies.
Policy set attachment – In order to apply policy sets to Web services, they need to be attached.    Bindings – Policy sets are meant to be reused across Web services and thus do not contain environment specific settings such as key stores or passwords. Instead, a binding contains these environment specific values.
WebSphere Application Server V7 comes prepackaged with 18 policy sets to simplify getting started. They are production-level policy sets that you can begin using immediately. WebSphere Application Server V7 also comes with 4 sample bindings, but these are for demonstration purposes only. For production Web services, you should customize the policy set bindings as described below.
Here we are going to implement confidentiality (such as encryption - one way) and propagate security tokens for authentication (such as username and password) in SOAP messages.
We are not going to touch integrity (such as digital signatures) verification and two way encryption as it requires client 's public certificate to be maintained on provider's server. So every time when new consumer comes in, we need to import that client's public certificate into different trust store of Provider Server.

a)    Creating service provider keys

                There are a number of tools for creating public key/private key pairs, but for this tutorial use the keytool command provided by the Java Development Kit (JDK), since it will be available with standalone clients as well as with WebSphere Application Server.
                The first thing we need to do is create a key store to hold provider's public and private keys. This can be accomplished with the following keytool command:
1.       In Microsoft Windows, select Start > Run…, then enter cmd in the Open field of the dialog box and click OK.
2.       In the Command Prompt window, change directories to where WebSphere Application Server V7 is installed. (e.g. cd c:\Program Files\IBM\SDP\runtimes\base_v7_stub)
3.       Now run the following keytool command:

java\bin\keytool.exe -genkey -alias server1 -keyalg RSA -keystore helloServerKeys.jks -storepass f00bar -dname "cn=server1,O=sample,C=US" -keypass passw0rd

This command generates a public key and private key pair that will be accessed via the server1 alias. Additionally, this command self signs the public key. Both private and public keys are stored in the helloServerKeys.jks file, which is password protected.
4.       Next, you need to export your server1 certificate to be imported into your client-side cert store later on, with the following keytool command:

java\bin\keytool.exe -export -alias server1 -file server1.cert -keystore helloServerKeys.jks -storepass f00bar



5.       Copy the service provider’s key ring 'helloServerKeys.jks' to the following directory 'profiles\<profile name>\config\cells\<cell name>'

On my machine the path is - C:\IBM\WebSphere\wp_profile\config\cells\portal\helloServerKeys.jks

b)    Creating service consumer trust store

                Now that you have created the server-side keys, next you create a client-side key store.
                Import the server-side public key into the client-side keys using the following keytool command :
                java\bin\keytool.exe -import -noprompt -alias server1 -file server1.cert -keystore myclientkeys.jks -storepass g00ber
                Copy client's trust store myclientkeys.jks into RAD project folder 'HelloWorldConsumer\WebContent\WEB-INF'
                Note - Recall above that you exported the public key of the server1 alias, which is the key pair that is associated with your service provider. Therefore, you need to import this public key into the client-side key store (i.e myclientKeys.jks). Then, when the service consumer (i.e. client-side) wants to encrypt a message for the service provider, the WS-Security configuration associated with the client will specify the server1 alias public key in the client’s key store.

c)     Creating a policy set

1.       From the Administrative Console, select Services > Policy sets > Application policy sets
2.       Click the checkbox next to the Username WSSecurity default, then click the Copy… button.
The Username WSSecurity default policy set encrypts the SOAP body, the signature, and the Username token. Additionally, the Username WSSecurity default policy set signs the SOAP body, the timestamp, the addressing headers, and the Username token. Message authentication is provided using the Username token. As this policy set provides defaults that are likely to be used frequently in real-life scenarios.

3.       Enter HelloWorldPolicySet as the name for your new policy set and any description you’d like in the description field. Click the OK button and Save link.
4.       Click on HelloWorldPolicySet > WS-Security > Main Policy
5.       By default, the WS-Security policy is created with message-level protection with signature verification and two way encryption, in order to simplify things, we will have one way encryption and without signature validation.
6.       To remove the request signed part - Click on 'Request message part protection'. Select 'app_signparts' and click on Delete button next to it. Click on Save link then click on Done button.


7.       Remove response message parts signature and encryption details- Click on 'Response message part protection'. Select 'app_encparts' and click on Delete button next to it. Select 'app_signparts' and click on Delete button next to it. Click on Save link then click on Done button.

8.       Remove Timestamp from both request and response. You cannot do one-way Timestamp - Uncheck the 'Include timestamp in security header ' then click on OK button and Save link.

d)    Creating a policy set binding

1.       In the Services menu, expand the Policy sets folder and select the General provider policy set bindings link. This link displays the list of provider policy set bindings.
2.       Click the checkbox next to the Provider sample policy set bindings, then click the Copy… button.
3.       Enter HelloWorldProviderBindings as the name for the new bindings and any desired text for the description field (optional), as shown below

4.       Click OK button and Save link

e)    Configuring service provider policy set binding

                The provider sample that you started with is for demonstration purposes only, and you must change the keys to provide production-level security. Therefore, you now need to customize your new policy set binding by changing the sample keys to use the real keys that you generated above.
                To customize the policy set binding to specify which certificates you trust:
1.       Navigate to the Keys and certificates policy bindings by clicking HelloWorldProviderBindings > WS-Security > Keys and certificates.
2.       Scroll down the page to the Trust anchor section and click the New… button.
3.       Enter HelloServerTrustStore in the name field then click the External keystore radio button.
4.       Enter ${USER_INSTALL_ROOT}\config\cells\<yourCellName>\helloServerKeys.jks for the full path to the external key store.
For simplicity, we use the hard-coded path to the key store. Normally, you would create a new WebSphere variable (e.g. MY_KEY_STORE) that would point to the absolute path so that you wouldn’t need to change your policy set bindings when moving from one cell to another.
5.       Select JKS as the key store type.
6.       Enter f00bar as the key store password. Your screen should look something like

7.       Click the OK button and Save link to save the changes.

        To customize the binding for encryption and decryption protection:

1.       Navigate to the Authentication and protection bindings by clicking HelloWorldProviderBindings > WS-Security > Authentication and protection. This step displays a window like the one below

2.       Select con_encx509token > Callback handler. Then choose Custom from the drop-down in the Key store section followed by clicking the Custom keystore configuration link.
3.       Change the values to match this table:
Field
Value
Keystore path
${USER_INSTALL_ROOT}\config\cells\<yourCellName>\helloServerKeys.jks
Keystore type
JKS
Keystore password
f00bar
Key name
cn=server1,o=sample,c=US
Key alias
server1
Key password
passw0rd
Notice that you have to enter the key’s password in addition to the key store password since you are accessing the private key.
The results should look similar to Figure below

4.       Click the OK button and Save link to save the key store configuration changes.
To customize the security tokens for authentication
1.       Navigate to the Caller bindings by clicking HelloWorldProviderBindings > WS-Security > Caller
2.       Click on New button
3.       Enter Caller for the Name.
4.       Enter http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken for the Caller identity local part. Note that this URL is the value of the Local part of the authentication token

5.       Click OK to accept this caller, then click Save to save this binding to the master configuration.

f)      Exporting a policy set and policy set binding

                Exporting a policy set
                Exporting is required to attach the policy set to the service provider using Rational Application Developer such that the policy set will get attached when deployed from Rational Application Developer.
1.       From the Administration Console, select Services > Policy sets > Application policy sets
2.       Click the checkbox next to the HelloWorldPolicySet then click the Export… button.

3.       Click the HelloWorldPolicySet.zip link and save the file to c:\temp. Click the OK button to save the file.

Exporting a policy set binding
Just as you exported the copied policy set above, you can also export the policy set bindings. Because this policy set binding is only for the service provider (i.e. server-side), it isn’t necessary to export this policy set binding. However, doing so allows you to attach the binding to the service provider in Rational Application Developer, which simplifies policy set attachment during development.
1.       In the Services menu, expand the Policy sets folder. Select the General provider policy set bindings link to display the list of provider policy set bindings.
2.       Click the checkbox next to the HelloWorldProviderBindings policy set bindings, then click the Export… button.
3.       Click the HelloWorldPolicySet.zip link as shown below and save the file to c:\temp. Click the OK button to save the file.



4.     Securing the service provider

Now that you have created a custom policy set and policy set binding (which you exported to c:\temp) you need to import them into the HelloWorldProject to attach them to the service provider. Recall that policy sets provide a declarative way to provide qualities of service (QoS) for Web services. By attaching a policy set and binding to a Web service, you are declaratively specifying what QoS to use.
a)      Login to the admin console and select Services > Services providers. You should see the HelloWorldProviderService listed in the service providers.
b)      Click the HelloWorldProviderService to drill into this service.
c)       Select service ' HelloWorldProviderService ' and then chose HelloWorldPolicySet  from 'Attach Policy Set' Dropdown and HelloWorldProviderBindings   from 'Assign Binding' dropdown. Save your changes.
d)      Switch to RAD. Right click on project 'HelloWorldProject' choose Import > Web services > WebSphere Policy Sets. Now click the Next button
e)      Click the Browse… button and choose the HelloWorldPolicySet.zip file that you exported to c:\temp above.
f)       The wizard reads the zip file and lists the policy sets included in the file. Click the checkbox next to HelloWorldPolicySet, then click the Finish button.

g)      As in the steps above, right-click HelloWorldProject and choose Import > Web services > WebSphere Named Bindings. Now click the Next button
h)      Click the Browse… button and choose the HelloWorldProviderBindings.zip file that you exported to c:\temp above.
i)        Again, the wizard reads the zip file and list the policy set bindings included in the file. Click the checkbox next to HelloWorldProviderBindings, then click the Finish button.

Once the policy set and bindings have been imported into Rational Application Developer, you can attach them to the service provider.

j)        In Rational Application Developer, drill into the HelloWorldProject > Services > HelloWorldProviderService then right-click and choose Manage policy set attachment… as shown below

k)      Click the Add button add a policy set and binding to an endpoint.
l)        Leave the scope set to the entire service and choose HelloWorldPolicySet from the drop-down for the policy set and HelloWorldProviderBindings from the drop-down for the binding as shown below

m)    Click the OK button to save this association.
n)      Click the Finish button to close the policy set attachment dialog box.

Now that you have attached the policy set and bindings to the service provider, you will deploy the service provider onto the WebSphere Application Server runtime and verify that our policy set and bindings have been attached.
To deploy the service provider and consumer :
a)      Clean and Build.. Provider and Consumer project from RAD
b)      Since these application are already deployed from RAD, just do a publish.. it will push new changes to server
c)       When the server finishes deploying and publishing, use the Administrative Console to verify that the service provider was successfully deployed to WebSphere Application Server and that the policy set and bindings have been attached.
d)      Login to the admin console and select Services > Services providers. You should see the HelloWorldProviderService listed in the service providers.
e)      Click the HelloWorldProviderService to drill into this service.
f)       You should now see the HelloWorldPolicySet attached as the policy set and HelloWorldProviderBindings attached for the binding as shown below


If you do not see the HelloWorldPolicySet  and HelloWorldProviderBindings  attached with HelloWorldProviderService in the service providers window then attach it manually. First select service ' HelloWorldProviderService ' and then chose HelloWorldPolicySet  from 'Attach Policy Set' Dropdown and HelloWorldProviderBindings   from 'Assign Binding' dropdown. Save your changes at end.

5.     Consuming a secure service

We already having ClientTest.jsp in consumer project 'HelloWorldConsumer '. We need to customize this jsp to pass credentials(username token) and soap message in encrypted format. Because the service provider is protected and expecting encrypted soap message according to the specifications of the Username WS-Security default policy set, you need to use the WSS APIs to build a SOAP message programmatically that adheres to the service provider's policy set.
Copy the following code into the ClientTest.jsp file and save the file.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1" import="java.util.Map,javax.xml.ws.BindingProvider,com.sample.*,com.ibm.websphere.wssecurity.wssapi.*,com.ibm.websphere.wssecurity.wssapi.encryption.WSSEncryption, com.ibm.websphere.wssecurity.wssapi.signature.WSSSignature, com.ibm.websphere.wssecurity.wssapi.token.*, com.ibm.websphere.wssecurity.callbackhandler.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
try {
                                String KEY_PATH = application.getRealPath("/WEB-INF/");
                                HelloWorldProviderService srv = new HelloWorldProviderService();
                                HelloWorldProviderDelegate port = srv.getHelloWorldProviderPort();
                               
                                // use BindingProvider to hook into message context
                                  BindingProvider bp = (BindingProvider) port;
                                  Map requestContext = bp.getRequestContext();
                                 
                                  WSSFactory wssfactory = WSSFactory.getInstance();
                                  WSSGenerationContext generationContext = wssfactory.newWSSGenerationContext();
                                 
                                // Attach the username token to the message
                                  UNTGenerateCallbackHandler untCallback = new
                                    UNTGenerateCallbackHandler("wpsadmin", "wpsadmin",true,true);
                                  SecurityToken unt = wssfactory.newSecurityToken(UsernameToken.class,
                                    untCallback);
                                  generationContext.add(unt);
                                 
                                  // specify key to use for encryption (same key service provider expecting)
                                  X509GenerateCallbackHandler encryptionCallback = new
                                    X509GenerateCallbackHandler("",
                                    KEY_PATH + "myclientkeys.jks",
                                    "jks", "g00ber".toCharArray(),"server1", null, "cn=server1,O=sample,C=US",null);
                                  SecurityToken encryptingToken = wssfactory.newSecurityToken(X509Token.class,
                                    encryptionCallback);
                                  WSSEncryption encryption = wssfactory.newWSSEncryption(encryptingToken);
                                  encryption.setKeyEncryptionMethod(WSSEncryption.KW_RSA15);
                                                                               
                                  // specify what to encrypt
                                  encryption.addEncryptPart(unt, false);
                                  encryption.addEncryptPart(WSSEncryption.BODY_CONTENT);
                                  encryption.addEncryptPart(WSSEncryption.SIGNATURE);
                                  generationContext.add(encryption);

                                  // encode message according to generationContext setting
                                  generationContext.process(requestContext);
                                                                  
                                String resp = port.sayHello("World");
                                out.println("[response] " + resp);
                                } catch (Exception e) {
                                                e.printStackTrace();
                                }
 %>
</body>
</html>


Restart your application server.

6.     Testing secure JAX-WS

a)      From Rational Application Developer, right-click ClientTest.jsp and select Run As => Run On Server
b)      Now click Finish to generate client results

c)       You can also use the TCP/IP monitor to see the SOAP request and response messages


7.     Important Links



No comments:

Post a Comment