Static JAX-WS Proxy Client
Oracle JDeveloper provides design-time support to generate a static JAX-WS proxy client to invoke a web service. In JDeveloper, you can create an application with a project and then create a new Web Service Proxy by selecting Business Tier > Web Services in the New Gallery page. Creating the proxy generates client-side proxy classes. You can then write client-side code to invoke the required service.
public class SvcInvoker {
@WebServiceRef
private static ExpenseService_Service expenseService_Service;
public static void main(String[] args) throws ServiceException, Exception {
expenseService_Service = new ExpenseService_Service();
SecurityPolicyFeature[] features =
new SecurityPolicyFeature[] { new SecurityPolicyFeature("policy:oracle/wss_username_token_over_ssl_client_policy") };
//or any other policy, as required
ExpenseService expenseService =
expenseService_Service.getExpenseServiceSoapHttpPort(features);
……//security setting code goes here
//invoke the service
FindCriteria fc = new FindCriteria();
fc.setFetchSize(1);
List<Expense> exps = expenseService.findExpense(fc, null);
if (exps != null && !exps.isEmpty()) {
Expense exp = exps.get(0);
//access the expenses
} else
System.out.println("No expenses");
}
}
Client-Side Security Policy
-
Transport Layer security policies:
-
oracle/wss_username_token_over_ssl_client_policy
-
oracle/wss_http_token_over_ssl_client_policy
-
oracle/wss_saml_token_bearer_over_ssl_client_policy
-
-
Message protection policies:
-
oracle/wss11_username_token_with_message_protection_client_policy
-
oracle/wss11_saml_token_with_message_protection_client_policy
-
For the transport layer security policies, the client uses the Secure Socket Layer (SSL) protocol on the server to invoke a web service. In Oracle Applications Cloud, the SSL protocol is enabled on the server by default. To use the message protection policies, the client imports the public key certificate from the server.
-
Client signing certificate is issued from a Certificate Authority (CA)
-
CA certificate is in the server trust store
-
SAML assertion carry the signing certificate
If the client-side is on the Oracle Applications Cloud, for example, when the client is deployed in Java Cloud Service, and linked to the corresponding Oracle Applications Cloud instance, the certificate exchange is already configured. You need to decide which client-side policy to use, based on the nature of the client and the requirements of each policy.
Security Configuration
The security configuration required for different client-side security policies are as follows:
oracle/wss_username_token_over_ssl_client_policy
For this policy, the service endpoint URL must use HTTPS protocol, and no configuration is required. The static proxy client-side code specifies the user name and password:
WSBindingProvider wsbp = (WSBindingProvider)expenseService;
Map<String, Object> requestContext = wsbp.getRequestContext();
requestContext.put(com.sun.xml.ws.developer.WSBindingProvider.USERNAME_PROPERTY,
"user");
requestContext.put(com.sun.xml.ws.developer.WSBindingProvider.PASSWORD_PROPERTY, "password");
Though this is the simplest method, the recommended method is
to store the user name and password in a credential store, and use a csf-key
to refer to the entry in the credential
store. Use Oracle JDeveloper to create a credential store when you are generating
the web service proxy. You can also edit the properties of the proxy object after it
is generated by selecting Override
Properties > New
Key.
-
cwallet.sso
file: Credential store -
jps-config.xml
file: Security context of your program. It contains the entry pointing to thecwallet.sso
credential store.
The client-side code must specify the location of the jps-config.xml
file and the csf-key
value.
System.setProperty("oracle.security.jps.config", "path_to_jps-config.xml");
expenseService_Service = new ExpenseService_Service();
SecurityPolicyFeature[] features = new SecurityPolicyFeature[] {
new SecurityPolicyFeature("policy: oracle/wss_username_token_over_ssl_client_policy " };
ExpenseService expenseService =
expenseService_Service.getExpenseServiceSoapHttpPort(features);
WSBindingProvider wsbp = (WSBindingProvider)expenseService;
Map<String, Object> requestContext = wsbp.getRequestContext();
requestContext.put(SecurityConstants.ClientConstants.WSS_CSF_KEY, "csf-key");
oracle/wss_http_token_over_ssl_client_policy
The requirements for this policy are same as the oracle/wss_username_token_over_ssl_client_policy
policy. While this
policy sets the authentication information in the HTTP header, the oracle/wss_username_token_over_ssl_client_policy
policy sets the
authentication information in the SOAP header.
oracle/wss_saml_token_bearer_over_ssl_client_polic
This policy uses SAML token, and requires a keystore in the client that contains the client signing and encryption keys. The server needs to import the public key certificate from the client.
-
Generate keystore in the client: Use keytool provided by JDK to generate the keystore, which stores the security certificate. To generate a
.jks
file, which is the keystore:keytool -genkeypair -keyalg RSA -alias mycompkey -keypass password -keystore mycompclient-keystore.jks -storepass password -validity 3600
-
Export certificate from the client: Use the following keytool command to export the certificate:
keytool -exportcert -alias mycompkey -file clientpubkey.cer -keystore mycompclient-keystore.jks -storepass password
-
Import certificate to the server: Use the following keytool command to import the certificate generated by the client to the server keystore as a trusted certificate entry:
keytool -importcert -alias clientkey -file clientpubkey.cer -keystore default-keystore.jks -storepass password
-
Add keystore to the client security context: The proxy client-side code must provide the keystore, signing key and encryption key that are protected by passwords. Use Oracle JDeveloper to import the keystore, set the password, and set the keystore in the client-side security context.
-
Proxy client-side code: The
WSSEC_SIG_KEY_ALIAS
andWSSEC_ENC_KEY_ALIAS
are used to specify the signing and encrypting private keys on the client side. This private key must be the same as the one used to generate the certificate. This code request uses SAML token, so the user name is passed but not the password. The client-side code can configure the security as:System.setProperty("oracle.security.jps.config", " path_to_jps-config.xml"); String policy = "oracle/wss_saml_token_bearer_over_ssl_client_policy"; expenseService_Service = new ExpenseService_Service(); SecurityPolicyFeature[] features = new SecurityPolicyFeature[] { new SecurityPolicyFeature("policy:" + policy) }; ExpenseService expenseService = expenseService_Service.getExpenseServiceSoapHttpPort(features); WSBindingProvider wsbp = (WSBindingProvider)expenseService; Map<String, Object> requestContext = wsbp.getRequestContext(); //client-side private signing key requestContext.put(ClientConstants.WSSEC_SIG_KEY_ALIAS, "mycompkey"); //client-side private encryption key requestContext.put(ClientConstants.WSSEC_ENC_KEY_ALIAS, "mycompkey"); //location of the keystore file requestContext.put(ClientConstants.WSSEC_KEYSTORE_LOCATION, "path_to_ mycompclient-keystore.jks"); requestContext.put(WSBindingProvider.USERNAME_PROPERTY, "username");
oracle/wss11_username_token_with_message_protection_client_policy
Using this policy, the web service consumer inserts username and password credentials, and signs and encrypts the outgoing SOAP message. The web service provider decrypts and verifies the message and the signature. This policy requires that the client imports the public key from the server.
-
Generate keystore in the client: Use keytool provided by JDK to generate the keystore, which stores the security certificate. To generate a
.jks
file, which is the keystore:keytool -genkeypair -keyalg RSA -alias mycompkey -keypass password -keystore mycompclient-keystore.jks -storepass password -validity 3600
-
Generate public key certificate: The client requires the public key from the server. The WSDL file contains the certificate in the
wsdl:service/wsdl:port/wsa:EndpointReference/wsid:Identity/dsig:keyInfo/dsig:X509Data/dsig:X509Certificate
element. Create a text file and enclose the certificate element with ---- BEGIN CERTIFICATE ---- and ---- END CERTIFICATE ---- statements. Save this text file aspk.cer
.<wsdl:service name="ExpenseService"> <wsdl:port name="ExpenseServiceSoapHttpPort" binding="tns:ExpenseServiceSoapHttp"> .... <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing"> <wsid:Identity xmlns:wsid="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity"> <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> <dsig:X509Data> <dsig:X509Certificate>MIICHTCCAYagAwIBAgIEUG1GfDANBgkqhkiG9w0BAQUFADBTMR MwEQYKCZImiZPyLGQBGRYDY29tMRYwFAYKCZImiZPyLGQBGRYGb3JhY2xlMRIwEA YKCZImiZPyLGQBGRYCdXMxEDAOBgNVBAMTB3NlcnZpY2UwHhcNMTIxMDA0MDgx OTA4WhcNMTUxMDA0MDgxOTA4WjBTMRMwEQYKCZImiZPyLGQBGRYDY29tMRYw FAYKCZImiZPyLGQBGRYGb3JhY2xlMRIwEAYKCZImiZPyLGQBGRYCdXMxEDAOBgN VBAMTB3NlcnZpY2UwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMvYgi3PpA9T vD6YptxWZDy6nusDfJYrQe5Q3cYjtR54exM8Ju29z2Mtk98HEZXMs2+GqNO7Ms8QZQ2Owl nuS0VZNMUQu3MkjM4UKyK+37H32jud3HP5jigpJARgtxfH1Z1RK4VovU1VFPeRULG+7em CvdfOks5o6dTPmH1xpsXLAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAguzjcfLzQUH5d O4jER9g4xrmjxZrKo8YC2xxGKzpxuMSg3EUhUPOznzZFv09+sIO2UFGpPV5NqNWlvFqej3 VBSal2HfGUQgMRe+kPV6ysAWvZ4T1pOxj4NDeWRUMjgjt14OXEOxifPbLhvOmiC8dD9d FwcdWh7lMMcwz0VM9F0M=</dsig:X509Certificate> </dsig:X509Certificate> ......
-
Import certificate to the client: Use the following keytool command to import the certificate to the client keystore:
keytool -importcert -alias pubkey -file pk.cer -keystore mycompclient-keystore.jks -storepass password
-
Configure client security context: The proxy client-side code must provide the keystore, signing key and encryption key that are protected by password. Use Oracle JDeveloper to create the
csf-key
that stores the user/password, import the keystore, and then set the password and keystore in the client-side security context. -
Proxy client-side code: The client-side code can now configure the security as:
System.setProperty("oracle.security.jps.config", “ path_to_jps-config.xml"); String policy = "oracle/wss11_username_token_with_message_protection_client_policy"; expenseService_Service = new ExpenseService_Service(); SecurityPolicyFeature[] features = new SecurityPolicyFeature[] { new SecurityPolicyFeature("policy:" + policy) }; ExpenseService expenseService = expenseService_Service.getExpenseServiceSoapHttpPort(features); WSBindingProvider wsbp = (WSBindingProvider)expenseService; Map<String, Object> requestContext = wsbp.getRequestContext(); //location of the keystore file requestContext.put(ClientConstants.WSSEC_KEYSTORE_LOCATION, "path_to_mycomp-keystore.jks"); requestContext.put(SecurityConstants.ClientConstants.WSS_CSF_KEY, "csf-key");
oracle/wss11_saml_token_with_message_protection_client_policy
This policy uses both message protection and SAML token. To configure message protection, the client-side keystore must import the public key certificate from the server. To use SAML token, the server must import the certificate from the client.
-
Generate keystore in the client: Use keytool to generate the keystore, which manages the private and public keys:
keytool -genkeypair -keyalg RSA -alias mycompkey -keypass password -keystore mycompclient-keystore.jks -storepass password -validity 3600
-
Generate server-side public key certificate: For this policy, the client requires the public key generated on the server side. The WSDL file contains the certificate in the
wsdl:service/wsdl:port/wsa:EndpointReference/wsid:Identity/dsig:keyInfo/dsig:X509Data/dsig:X509Certificate
element. Create a text file and enclose the certificate element with ---- BEGIN CERTIFICATE ---- and ---- END CERTIFICATE ---- statements. Save this text file aspk.cer
. -
Import certificate to the client: Use the following keytool command to import the certificate generated by the server to the client keystore:
keytool -importcert -alias pubkey -file pk.cer -keystore mycompclient-keystore.jks -storepass password
-
Export certificate from the client: Use the following keytool command to export the certificate:
keytool -exportcert -alias mycompkey -file clientpubkey.cer -keystore mycompclient-keystore.jks -storepass password
-
Import client-side certificate to server: Use the following keytool command to import the certificate generated by the client to the server keystore as a trusted certificate entry:
keytool -importcert -alias clientkey -file clientpubkey.cer -keystore default-keystore.jks -storepass password
-
Configure client security context: The proxy client-side code must provide the keystore, signing key, and encryption key that are protected by password. Use Oracle JDeveloper to import the keystore, and then set the password and keystore in the client-side security context.
-
Proxy client-side code: The
WSSEC_SIG_KEY_ALIAS
andWSSEC_ENC_KEY_ALIAS
are used to specify the signing and encrypting private keys on the client side. This private key must be the same as the one used to generate the certificate. This code request uses SAML token, so the user name is passed but not the password. The client-side code can configure the security as:Note: This sample code works only in a JSE environment. In JEE environment, usually the current user is propagated to the server. The client and server need to share identity store, use identity federation, or the client side uses Security Token Service (STS) to map the client credential to the server credential.System.setProperty("oracle.security.jps.config", "path_to_jps-config.xml"); String policy = "oracle/wss11_saml_token_with_message_protection_client_policy"; expenseService_Service = new ExpenseService_Service(); SecurityPolicyFeature[] features = new SecurityPolicyFeature[] { new SecurityPolicyFeature("policy:" +policy)}; ExpenseService expenseService = expenseService_Service.getExpenseServiceSoapHttpPort(features); WSBindingProvider wsbp = (WSBindingProvider)expenseService; Map<String, Object> requestContext = wsbp.getRequestContext(); requestContext.put(ClientConstants.WSSEC_SIG_KEY_ALIAS, "mycompkey"); requestContext.put(ClientConstants.WSSEC_ENC_KEY_ALIAS, "mycompkey"); //location of the keystore file requestContext.put(ClientConstants.WSSEC_KEYSTORE_LOCATION, “ path_to_mycomp-keystore.jks"); requestContext.put(WSBindingProvider.USERNAME_PROPERTY, "username");