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
- Installed JDeveloper 10g (10.1.3)
- 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
- A JDeveloper Connection to
running OC4J:
- Click the Connections tab (If the Connections
tab is not visible, choose View > Connection Navigator from the
menu).
- Right-click the Application Server node and
select New Application Server Connection from the
context menu.
- If the Welcome page of the Create Application
Server Connection wizard displays, click Next.
- On the Type page of the wizard, enter the Connection
Name of oc4j_local and click Next.
- 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.
- On the Connection page of the wizard, click
Next.
- 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. )
- 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
- Open a command prompt
- Navigate to <JDEV_HOME>\jdk\bin
- 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
- Enter keystore password: mytestkeystore
- Enter key password for sam: sampwd
Add a key for dave in the same keystore
- 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
- Enter keystore password:mytestkeystore
- Enter key password for dave: davepwd
Review the contents of the generated
keystore
- Enter the following code to display the contents
of the keystore
keytool -list -v -keystore c:\temp\mytestkeystore.jks
- Enter keystore password: mytestkeystore
For more detailed information on using Keytool
see the link above
Create an Empty Application
and Project.
- Open the New Gallery by choosing File
then choose New.
- In the New Gallery, in the Categories tree, select
General.
-
In the Items list, double-click Application.
- In the Create Application dialog, enter WSSecurityDemo
as the application name and click OK

- 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.
- Open the New Gallery by choosing File
then choose New
- In the New Gallery, in the Categories tree, select
General
- In the Items list, double-click Java Class
- In the Create Java Class dialog, enter SimpleWSImpl
as the class name and click OK

- In the source editor, add
the following lines to the Java Class
public String echoMe(String s) {
return s;
}

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

- Choose J2EE 1.4 (JAX-RPC Web Service)

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

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

- In the Web Services Editor, on the Security
page, click the checkbox under Ports for MyWebService1SoapHttpPort
- 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)
- Under Security, select the Authentication page
- 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.
- Under Security, select the Inbound
Integrity page
- 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.
- Under Security, select the
Outbound Integrity page
- 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
- Under Security, select the Keystore
Options page
- For the Keystore Path, Browse to
the location of the keystore
- Enter the Keystore Password, in
this example mytestkeystore
Note: this password is needed to
access the keystore and retrieve the Key aliases
- 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
- Under Security, select Outbound Confidentiality
- 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
- Under Inbound Confidentiality, accept
defaults
Generate oracle-webservices.xml
- 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
- 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
- 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)
- Click OK to close
- 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)

- 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
- 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)
- Enter Username and Password (default oc4jadmin/welcome)
to login
- Click the Applications tab to see
all the deployed applications
- Click the link to the deployed
application - WSSecurityHowTo
- In the Application:WSSecurityHowTo page, click the
Administration tab
- Click on the Go to Task icon for
Security Provider

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

- In the Users page, click Create
to add a new User
- Username: albert
- Password: albert
- Click OK to create

- Click the link: Application:WSSecurityDemo-Server-WS
Add Web Service Level
Keystore Password Information
- In the Application:WSSecurityHowTo-Server-WS page,
click the Web Services tab
- On the Web Services tab, click the MyWebService1SoapHttpPort
link
- Click on the Administration tab
to review the management features
Note the Security entry is Enabled
- Click on the Edit
Configuration icon for Security
- Click on Keystore and Identity Certificates
- Add a Keystore Name, in this example mytestkeystore
- Add and confirm the Keystore Password, in this example
mytestkeystore
- Add and confirm the Signature
Key password, in this example sampwd
- Add and confirm the Encryption Key password in this
example davepwd
- Click OK
to save entries

Create
a Secured Client Proxy and Test the Secured Web Service
Create a New Project
- Select the Application node in the Application
- Use the context menu to create a New Project
- Name the project Client
Create a Web Service Proxy
- In the Application Navigator,
select the Client project
- Use the context menu of Client to open the New
gallery
- Under Categories > Business Tier, select
Web Services
- Under Items select Web Service Proxy
- Select the MyWebService1.wsdl from
the drop down list.
The Service Name and Mapping file information
will be populated from the service details
- Click Next
- 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
- Accept all other defaults and click Finish
to generate proxy
Secure the Proxy
- Use the context menu of MyWebService1Proxy to Secure
Proxy
- On Page , 2, 3 of wizard - accept defaults.
Note: This sets the client proxy to the
same security settings as the secured service
- On Page 4 add the Encryption Key Alias of dave
- this was also used in the service
- On Page 5 - accept defaults.
Mote: Pages 4,5 set up the proxy to send
and receive encrypted messages, as the service expects
- 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
- Click Next and Finish to generate
the Proxy security settings into the MyWebService1SoapHttp_Stub.xml
file
Add
Passwords to Proxy
- In the Application Navigator, select MyWebService1Proxy
- 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)
- Double click on the file to open it
- Click in the open file in the code editor
- In the Structure Pane, expand port-info
> runtime > security nodes
- Double-click on key-store
- Add the name and store-pass property values, in this
example mytestkeystore
- Double-click on signature-key
- Add the key-pass value for sam, in this example sampwd

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

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

- Save All
- Rebuild the Client project so the
runtime files are updated
Run the Client
- In the Code Editor, select the MyWebService1SoapHttpPortClient.java
editor
- Add the following code to the main method
myPort.setUsername("albert");
myPort.setPassword("albert");
myPort.echoMe("testing secure service")
- Use the context menu of the class to Run the proxy
and call the service
- In the log window you should see the return
testing secure service
Use HTTP Analyzer to View Secured
SOAP Messages
- From the menu, choose Tools > Preferences
> Web Proxy Browser and turn off any proxy settings or exceptions
that will interfere with HTTP Analyzer
- From the menu, choose View > HTTP Analyzer
- Click green icon
to start the HTTP Analyzer

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

- Select the row for the call and click the Data
tab of HTTPAnalyzer
- Review signed and encrypted data sent in SOAP message
- 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 |