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.

For more information, see Creating a Web Service Proxy.
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

You must configure the security setting based on the client-side security policy used to invoke a service.
  • 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.

If the client side maintains the user identity to invoke a service, the username token policies are easier to use than the SAML token policies. The SAML token policies support identity propagation, but require certificate exchange between the server and the client, unless all of the following are true:
  • 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 the cwallet.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 and WSSEC_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 as pk.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 as pk.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 and WSSEC_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");
Related Topics
  • HTTP Client
  • Dynamic Dispatch Client
  • Java Client
  • Invoking SOAP Web Services