How to Use JDeveloper 10.1.3 to Secure and Test a Web Service


Written by Susan Duncan and Colin Maxwell, Oracle Corporation
May , 2006

Overview

This how to shows how JDeveloper 10.1.3 can be used to develop, secure and test a web service. JDeveloper provides a testing environment for securing and adding self-signed keypair integrity and encryption details to both the service and proxy to ensure the service is being used by an authenticated user, has not been tampered with in transit and cannot be read by a 'man-in-the-middle' attack.

Sun's Keytool utility is used to create RSA self-signed certificates in a keystore to test security of the service.

JDeveloper is used to deploy the secured service and keystore to OC4J. To maintain password security, the OC4J console is then used to add passwords from the keystore. JDeveloper is used to create a secure proxy to test the running, secured service. Finally, using the HTTP Analyzer, the developer can review the signed and encrypted SOAP messages being sent and received by the server.

Steps

Prerequisites

  1. Installed JDeveloper 10g (10.1.3)
  2. Started Oracle Application Server Containers for J2EE (OC4J) (<JDEV_HOME>\jdev\bin\start_oc4j.bat)
    If prompted for a password, enter welcome. Nothing displays as you enter the password (normal default is welcome). .
    Watch the resulting command window and wait until you see the message 'Oracle Containers for J2EE 10g (10.1.3.0.0) initialized'.
    Then you can minimize the window, but do not close it
  3. A JDeveloper Connection to running OC4J:
    1. Click the Connections tab (If the Connections tab is not visible, choose View > Connection Navigator from the menu).
    2. Right-click the Application Server node and select New Application Server Connection from the context menu.
    3. If the Welcome page of the Create Application Server Connection wizard displays, click Next.
    4. On the Type page of the wizard, enter the Connection Name of oc4j_local and click Next.
    5. On the Authentication page of the wizard, enter a Password of welcome (or whatever password was used when OC4J was initially started) and select Deploy Password, then click Next.
    6. On the Connection page of the wizard, click Next.
    7. On the Test page of the wizard, click Test Connection. After testing, the Status message should display Success!. (If it displays error messages, click Back and correct the connection information that you have entered. )
    8. Click Next, then Finish

Create a Keystore

In this example Sun's keytool utility is used to create a keystore with 2 self-signed certificates using the RSA algorithm

Create a key for sam in a new keystore

  1. Open a command prompt
  2. Navigate to <JDEV_HOME>\jdk\bin
  3. Enter the following code to create a key for Sam Moore in a new keystore called mytestkeystore at c:\temp. Change the location as appropriate

    keytool -genkey -dname "CN=Sam Moore, OU=samDept, O=samOrg, L=samHome, S=Florida, C=US" -keyalg RSA -sigalg Sha1WithRSA -keystore c:\temp\mytestkeystore.jks -alias sam

  4. Enter keystore password: mytestkeystore
  5. Enter key password for sam: sampwd

Add a key for dave in the same keystore

  1. Enter the following code to create a key for Dave Prater in mytestkeystore. Change the location as above

    keytool -genkey -dname "CN=Dave Prater, OU=daveDept, O=daveOrg, L=daveHome, S=Georgia, C=US" -keyalg RSA -sigalg Sha1WithRSA -keystore c:\temp\mytestkeystore.jks -alias dave
  2. Enter keystore password: mytestkeystore
  3. Enter key password for dave: davepwd

Review the contents of the generated keystore

  1. Enter the following code to display the contents of the keystore

    keytool -list -v -keystore c:\temp\mytestkeystore.jks
  2. Enter keystore password: mytestkeystore

For more detailed information on using Keytool see the link above

Create an Empty Application and Project.

  1. Open the New Gallery by choosing File then choose New.
  2. In the New Gallery, in the Categories tree, select General.
  3. In the Items list, double-click Application.


  4. In the Create Application dialog, enter WSSecurityDemo as the application name and click OK


  5. In the Create Project dialog, enter Server as the project name and click OK

Create a Java Class and Publish as a Web Service

Create a Java Class .

  1. Open the New Gallery by choosing File then choose New
  2. In the New Gallery, in the Categories tree, select General
  3. In the Items list, double-click Java Class
  4. In the Create Java Class dialog, enter SimpleWSImpl as the class name and click OK



  5. In the source editor, add the following lines to the Java Class

    public String echoMe(String s) {
    return s;
    }

Create Web Service

  1. In the Application Navigator, use the context menu of SimpleWSImpl.java to select Create J2EE Web Service


  2. Choose J2EE 1.4 (JAX-RPC Web Service)


  3. Accept all the other defaults and click Finish to generate the Web service

Secure the Web Service

  1. In the Application Navigator, use the context menu of MyWebService1 to Secure Web Service


  2. In the Web Services Editor, on the Security page, click the checkbox under Ports for MyWebService1SoapHttpPort
  3. Accept the default Authentication, Integrity and Confidentiality settings on the page
    This page sets the overally security profile for this Port of this service:
    1. Authentication - an application username/password will be used to authenticate that the service is being used by an authorised person. Alternatively an X509n certificate or SAML could have been used for authentication.
    2. Integrity and Confidentiality - certified users will be specified through their keys (in a keystore) to sign and encrypt the service



Set Authentication

Authentication: Is the user of the service authenticated to use it? In this example a username/password is used to authenticate the user (rather than the X509 certificate)

  1. Under Security, select the Authentication page
  2. Accept the defaults

Set Inbound Integrity

Inbound integrity: Has the message been tampered with in any way during its journey from the client to the server? The private key of the sender is used to sign the message and on receipt at the server the sender's public key is used to check the integrity of the message.

  1. Under Security, select the Inbound Integrity page
  2. Add a check to the Creation Time Required in Timestamp checkbox. All the checkboxes should now be checked


Set Outbound Integrity

Outbound integrity: Has the outgoing message been tampered with in any way during its journey from the server to the client? The public key of the client is used to sign the message and on receipt at the client the client's private key is used to check the integrity of the message.

  1. Under Security, select the Outbound Integrity page
  2. Add a check to the Creation Time Required in Timestamp checkbox. All the checkboxes should now be checked


Add Keystore Options

A keystore holds the certified keys of users and ties in the choices made in the previous pages for integrity and encryption

  1. Under Security, select the Keystore Options page
  2. For the Keystore Path, Browse to the location of the keystore
  3. Enter the Keystore Password, in this example mytestkeystore
    Note: this password is needed to access the keystore and retrieve the Key aliases
  4. From the dropdown lists select the Key Alias, in this example - sam for the Signature Key Alias and dave for the Encryption Key Alias
    Note that OC4J requires a separate key for signature and encryption

Set Outbound Confidentiality

Outbound Confidentiality: Has the message been read during its journey from the server to the client? The public key of the user is used to encrypt the message and on receipt at the cleint the client's private key is used to decrypt the message

  1. Under Security, select Outbound Confidentiality
  2. Set the Encryption Key Alias for the Public Key, in this example dave

Set Inbound Confidentiality

Inbound Confidentiality : Has the message been read during its journey from the client to the server? The private key of the sender is used to sign the message and on receipt at the server the sender's public key is used to decrypt the message

  1. Under Inbound Confidentiality, accept defaults

Generate oracle-webservices.xml

  1. Click OK to close the Web Services Editor and generate the oracle-webservices.xml file
    Note that this file now contains the security settings and is ready to be deployed with the web service
  2. Open the oracle-webservices.xml file in the editor.
    Note: the <signature-key> and <encryption-key> password elements of the keystore are blank. To maintain password security passwords should not be added to this file. They will be added to the deployed service later

Deploy the Secured Web Service

  1. In the Application Navigator, under the Resources node, use the context menu of Keystore.deploy to open the Properties dialog for the EAR Deployment Profile. Optionally, change the Application Name (in this case WSSecurityHowTo)



  2. Click OK to close
  3. Use the context menu of Keystore.deploy to Deploy to local_oc4j (the running OC4J instance)
    Note: Keystore.deploy deploys the keystore as well as the web service through the inclusion of the WebServices.deploy profile in the keystore property file (above)



  4. In the Configure Application dialog, accept all defaults, click OK

Set The Runtime Security for the Service

Add the Application Level Username/Password for Authentication

  1. In a browser, open the OC4J Enterprise Manager Application Server Control Console using URL http://localhost:8888/em (assuming OC4J instance is running on localhost)
  2. Enter Username and Password (default oc4jadmin/welcome) to login
  3. Click the Applications tab to see all the deployed applications
  4. Click the link to the deployed application - WSSecurityHowTo



  5. In the Application:WSSecurityHowTo page, click the Administration tab
  6. Click on the Go to Task icon for Security Provider


  7. In the Security Provider page, Click Realms
  8. Click Users to add a new user
    Note that this example is using the default File-Based Security Provider




  9. In the Users page, click Create to add a new User
  10. Username: albert
  11. Password: albert
  12. Click OK to create


  13. Click the link: Application:WSSecurityDemo-Server-WS

Add Web Service Level Keystore Password Information

  1. In the Application:WSSecurityHowTo-Server-WS page, click the Web Services tab
  2. On the Web Services tab, click the MyWebService1SoapHttpPort link



  3. Click on the Administration tab to review the ma nagement features
    Note the Security entry is Enabled
  4. Click on the Edit Configuration icon for Security

  5. Click on Keystore and Identity Certificates


  6. Add a Keystore Name, in this example mytestkeystore
  7. Add and confirm the Keystore Password, in this example mytestkeystore
  8. Add and confirm the Si gnature Key password, in this example sampwd
  9. Add and confirm the Encryption Key password in this example davepwd
  10. Click OK to save entries

Create a Secured Client Proxy and Test the Secured Web Service

Create a New Project

  1. Select the Application node in the Application
  2. Use the context menu to create a New Project


  3. Name the project Client

Create a Web Service Proxy

  1. In the A pplication Navigator, select the Client project
  2. Use the context menu of Client to open the New gallery
  3. Under Categories > Business Tier, select Web Services
  4. Under Items select Web Service Proxy



  5. Select the MyWebService1.wsdl from the drop down list.
    The Service Name and Mapping file information will be populated from the service details
  6. Click Next
  7. In Step 2 Select Run against a service deployed to an external server
    Note: This takes the endpoint to the deployed service from the WSDL file


  8. Accept all other defaults and click Finish to generate proxy

Secure the Proxy

  1. Use the context menu of MyWebService1Proxy to Secure Proxy


  2. On Page , 2, 3 of wizard - accept defaults.
    Note: This sets the client proxy to the same security settings as the secured service
  3. On Page 4 add the Encryption Key Alias of dave - this was also used in the service
  4. On Page 5 - accept defaults.
    Mote: Pages 4,5 set up the proxy to send and receive encrypted messages, as the service expects
  5. On Page 6 add the path to the keystore, the password ( mytestkeystore), the Signature Key Alias ( sam) and the Encryption Key Alias ( dave)
    Note: These must mirror the settings on the server




  6. Click Next and Finish to generate the Proxy security settings into the MyWebService1SoapHttp_Stub.xml file

Add Passwords to Proxy

  1. In the Application Navigator, select MyWebService1 Proxy
  2. In the Structure Pane, move the mouse over the MyWebService1SoapHttp_Stub.xml file and make sure that the path says
    ......\ client\runtime\MyWebService1SoapHttp_Stub.xml file
    Note: There are 2 copies of this file generated, ensure the runtime version is selected. (The other version sits on its own in the Application Navigator and is not used at runtime)
  3. Double click on the file to open it



  4. Click in the open file in the code editor
  5. In the Structure Pane, expand port-info > runtime > security nodes



  6. Double-click on key-store
  7. Add the name and store-pass property values, in this example mytestkeystore


  8. Double-click on signature-key
  9. Add the key-pass value for sam, in this example sampwd

  10. Double-click on encryption-key
  11. Add the key-pass value for dave, in this example davepwd



  12. In the code editor, check that the configuration file has been updated



  13. Save All
  14. Rebuild the Client project so the runtime files are updated

Run the Client

  1. In the Code Editor, select the MyWebService1SoapHttpPortClient.java editor
  2. Add the following code to the main method

    myPort.setUsername("albert");
    myPort.setPassword("albert");
    myPort.echoMe("testing secure service")




  3. Use the context menu of the class to Run the proxy and call the service
  4. In the log window you should see the return

    testing secure service

Use HTTP Analyzer to View Secured SOAP Messages

  1. From the menu, choose Tools > Preferences > Web Proxy Browser and turn off any proxy settings or exceptions that will interfere with HTTP Analyzer
  2. From the menu, choose View > HTTP Analyzer
  3. Click green icon to start the HTTP Analyzer


  4. Run MyWebService1HttpPortClient.java again
    Note: On the History tab the web service call should be listed



  5. Select the row for the call and click the Data tab of HTTPAnalyzer
  6. Review signed and encrypted data sent in SOAP message


  7. Click red square icon to stop HTTP Analyzer

Conclusion

Using JDeveloper it is possible to create, publish, secure and deploy web services to WS-Security standards. JDeveloper can be used as a test bed to call deployed services with all necessary security enabled and to view the results in the HTTP Analyzer. It is not recommended that JDeveloper is used to deploy secured web services to the live production system. That is more likely to be done by an administrator with security privileges or using Oracle's Web Service Manager to centrally manage security and management profiles of services.

Troubleshooting

Symptom Cause Soution
oracle.security.jazn.util.KeyStoreUtil loadKeystore
SEVERE: Error reading keystore data
java.io.IOException: Keystore was tampered with, or password was incorrect

client\runtime\MyWebService1SoapHttp_Stub.xml file has incorrect password entries.

Repeat the steps to add the password entry details into the client deployment descriptor.

Remember to 'Make' the XML file to copy it to the correct location for runtime.

javax.xml.rpc.soap.SOAPFaultException: An invalid token was provided
at oracle.j2ee.ws.client.StreamingSender._raiseFault(StreamingSender.java:553)

or in the OC4J console window:
2006-04-07 14:59:32.375 ERROR Invalid port config oracle.security.wss.config.SecurityPortImpl@fead77

06/04/07 14:59:32 java.lang.RuntimeException: Invalid port config : Error reading keystore data
06/04/07 14:59:32 at oracle.security.wss.interceptors.SecurityPortDescriptor.configure(Securit
yPortDescriptor.java:171)
06/04/07 14:59:32 at oracle.j2ee.ws.server.mgmt.runtime.mbean.ServerInterceptorPortRuntime.rec
onfigure(ServerInterceptorPortRuntime.java:108)
06/04/07 14:59:32 at oracle.j2ee.ws.server.mgmt.runtime.mbean.ServerInterceptorPortRuntime

 

The passwords have not been correctly populated for the running service using the OC4J Application Server Control

 

 

 

 

Or the keystore does have SKI (Subject Key Identifier) and a bug in 10.1.3 (bug 4996924) means that the fallback of using BST (Binary Security Token) to validate the key fails if using the Windows platform.

 

Repeat the steps to edit the web service security settings in the Oracle Application Server Control. Ensure the passwords are added in the appropriate places

 

Ensure the keystore has SKI (X509 V3). Using a keystore generated using keytool.exe will not work as it creates X509 V1 - with no SKI.

javax.xml.rpc.soap.SOAPFaultException: User [albert] does not exist in system.
at oracle.j2ee.ws.client.StreamingSender._raiseFault(StreamingSender.java:553)
at oracle.j2ee.ws.client.StreamingSender._sendImpl(StreamingSender.java:390)
at oracle.j2ee.ws.client.StreamingSender._send(StreamingSender.java:111)
at client.runtime.MyWebService1SoapHttp_Stub.echoMe(MyWebService1SoapHttp_Stub.java:78)
at com.cmaxwell.secure.MyWebService1SoapHttpPortClient.echoMe(MyWebService1SoapHttpPortClient.java:43)
at com.cmaxwell.secure.MyWebService1SoapHttpPortClient.main(MyWebService1SoapHttpPortClient.java:31)
The jazn-data.xml for the server project is not populated with the albertuser. Repeat the step to add the new Application user 'albert' in the OC4J application Server Control.
oracle.j2ee.ws.common.soap.fault.SOAP11FaultException: java.lang.NullPointerException
at oracle.j2ee.ws.common.mgmt.runtime.InterceptorChainImpl.createSoapFaultException(InterceptorChainImpl.java:329)

The client deployment descriptor (MyWebService1SoapHttp_stub.xml) has a problem with the

<verify-timestamp created="false" expiry="28800"/>

<add-timestamp created="false" expiry="28800"/>

This has to match on both the server and the client. For some reason the created="false" creates problems.

Have either

<verify-timestamp created="true" expiry="28800"/>

<add-timestamp created="true" expiry="28800"/>

In both server and client config files, or remove this line entirely from both config files.

WARNING: Unable to connect to URL: http://localhost:8888/Application1-service-context-root/MyWebService1SoapHttpPort due to java.security.PrivilegedActionException: javax.xml.soap.SOAPException: Message send failed: Connection refused: connect
java.rmi.RemoteException: ; nested exception is:
HTTP transport error: javax.xml.soap.SOAPException: java.security.PrivilegedActionException: javax.xml.soap.SOAPException: Message send failed: Connection refused: connect

The service has not been able to access the server.

or

The HTTP Analzer was not stopped before shutting down JDeveloper. This means that the Analyzer Port number of 8099 was left valid in the Web Browser and Proxy settings. Always turn of the Analyzer before closing JDeveloper down.

Check that the HTTP Proxy Server is not incorrectly setup. If you are working locally, turn it off (remove Port and any exceptions). Found at Tools -> Web Browser and Proxy

Where to get more information

Oracle Technology Network

JDeveloper 10g

Oracle Web Services Manager

Service-Oriented Architecture Center

Oracle Security Technology Center

 
false ,,,,,,,,,,,,,,,