Securing Services Using the AquaLogic Service Bus
Pages: 1, 2, 3, 4

Sample Client Application Creation

Now that the ALSB proxy Web service has been created, a sample client application needs to be created and run to test the service. For this example, WebLogic Server's toolkit for generating a Web service client is used. However, any WS-I- and WS-Security-compliant Web service toolkit could be used instead.

1. Create an Ant build file (for example, build.xml) that invokes the WebLogic Server's "clientgen" Ant task to generate SOAP stubs based on the WSDL of the remote Web service. For example, include the following in the build file:

<taskdef name="clientgen"
      classpathref="CLASSPATH"
      classname="weblogic.wsee.tools.anttasks.ClientGenTask" />

<clientgen wsdl="http://localhost:7001/EchoProxyService?WSDL"
     destDir="src" packageName="test" classpathref="CLASSPATH"
     generateAsyncMethods="false"/>

2. Using a text editor or IDE, create a simple Java class with a main method that uses WebLogic Server's JAX-RPC implementation to invoke the ALSB Echo proxy Web service, using the stub classes generated in the previous step. This file should then be compiled. Due to the fact that the JAX-RPC standard does not yet cover WS-Security elements, some of the APIs used to create the client application are vendor-specific. Below is an example test client source code you can use:

package test;

import java.util.*;
import java.security.cert.*;
import javax.xml.rpc.*;
import weblogic.security.SSL.*;
import weblogic.xml.crypto.wss.*;
import weblogic.xml.crypto.wss.provider.*;
import weblogic.wsee.security.bst.*;
import weblogic.wsee.security.unt.*;

public class EchoServiceClient {
 public static void main(String[] args) {
  try {
    // Point to the private/public key-pair identity keystore 
    // that will be used by the client for signing
    List<CredentialProvider> credProviders = 
       new ArrayList<CredentialProvider>();
    CredentialProvider cp = new ClientBSTCredentialProvider(
           "/opt/bea/domains/base_domain/wsidentity.jks", 
           "weblogic", "bob", "weblogic");
    credProviders.add(cp);

    // Get a handle on the Web service stub
    EchoService echoService = new EchoService_Impl(
          "http://localhost:7001/EchoProxyService?WSDL");
    Echo echoStub = echoService.getEcho();

    // Associate the key pair credentials with the Web 
    // service stub
    Stub baseStub = (Stub)echoStub;
    baseStub._setProperty(
       WSSecurityContext.CREDENTIAL_PROVIDER_LIST,credProviders);
    baseStub._setProperty(
       WSSecurityContext.TRUST_MANAGER, new TrustManager() {
        public boolean certificateCallback(X509Certificate[] chain, 
                                           int validateErr) {
            return true;
        } });

    // Call the Web service and display the result
    String result = 
         echoStub.doEcho("Hello from the client application");
    System.out.println("Service result is: " + result);
  } catch (Exception e) {
    System.err.println("Unable to invoke service: " + 
                       e.getMessage());
    e.printStackTrace();
  }
 }
}

3. Run the "test.EchoServiceClient" Java application from the command line to invoke the ALSB Echo service with a signed message and to display the service response. The following message should be printed to the console by the client application, if successful:

Service result is: Hello from the client application

Note that the client application needs to include WebLogic Server's webserviceclient.jar on its classpath.

What Has Been Accomplished?

The required PKI keys, certificates, and keystores have been created; WebLogic Server and ALSB have been configured to support WS-Security using these PKI artifacts: a WS-Security policy file has been defined that can then be applied to one or more services; and a proxy Web service has been created, using this security policy file. Finally, a test Web service client for this proxy service has been created and invoked, which signs the SOAP request sent to ALSB and includes the client's certificate.

Most of these configuration tasks only have to be undertaken once for the environment. To secure further proxied business services with the same security policy, each additional proxy service just needs to have its WSDL definition modified to reference the existing WS-Security policy file.

Access Control Configuration (Optional Extra)

The following steps need to be performed only if there is a need to apply access control to ALSB proxy services. A key pair for an additional user (Alice) is created to help test whether the access control settings are configured correctly. In the example, access control will be specified to permit Bob to access the service and to prevent Alice from accessing the service. The ALSB Access Control settings will be based on elements of the distinguished name (DN) contained with the certificate supplied by the client application.

1. Create a new public/private key pair for an additional sample user called "Alice" in the existing identity keystore in the domain's root directory:

> keytool -genkey
     -keyalg rsa -keystore wsidentity.jks -alias alice -keysize 1024
     -keypass weblogic -storepass weblogic -validity 3650

    What is your first and last name?
      [Unknown]:  alice 
    What is the name of your organizational unit? 
      [Unknown]:  IT
    What is the name of your organization?
      [Unknown]:  BEA
    What is the name of your City or Locality?
      [Unknown]:  LONDON
    What is the name of your State or Province?
      [Unknown]:  LONDON
    What is the two-letter country code for this unit?
      [Unknown]:  UK
    Is CN=alice, OU=IT, O=BEA, L=LONDON, ST=LONDON,
    C=UK correct?
      [no]:  yes

2. Export the self-signed certificate for this key pair to a base-64 encoded file called "alice.pem":

> keytool -export -alias alice -file alice.pem -keystore
             wsidentity.jks -storepass weblogic -rfc

3. Import the Alice's self-signed certificate into the existing trust keystore:

> keytool -import -alias alice -file alice.pem -keystore
             trust.jks-storepass weblogic

4. Using the WebLogic Admin Console, navigate to the Domain configuration page and select the tab WebService Security; then select the __SERVICE_BUS_INBOUND_WEB_SERVICE_SECURITY_MBEAN__ configuration, and then select the Token Handler tab. From the list of token handlers, select the "default_x509_handler" item. At the base of this page, select the token property handler "UseX509ForIdentity" and change its value to "true" (see the screenshot in Figure 13). Setting this property instructs the WebLogic Server's WS-Security implementation to attempt to use the x509 token to identify a client, using the token passed by the client application.

Figure 13
Figure 13. Proxy settings summary (click the image for a full-size screen shot)

5. Using the WebLogic Admin Console, navigate to the "myrealm" Security Realms page, select the tab Providers | Authentication, and select the "DefaultIdentityAsserter" item. Select the Provider Specific tab for this item and set the following field values: Default User Name Mapper Attribute Type = CN, Active Types = Authenticated User & X.509 and User Default User Name Mapper = true (see the screenshot in Figure 14). This instructs WebLogic Server to map the client application's common name (CN) in the certificate's distinguished name (DN) to a known username in WebLogic Server's Security Realm (for example, "bob," "alice").

Figure 14
Figure 14. Proxy settings summary (click the image for a full-size screen shot)

6. Restart WebLogic Server to enable the new security settings to be incorporated. Once, restarted, check the Active Types setting again in the Admin Console to ensure it includes the value "X.509" (check the page shown in the screenshot above).

7. Using the ALSB Admin Console, select the Security Configuration section, and create two new users, one called "bob" and one called "alice." These users are intended to correspond with the CNs of the key pairs created earlier.

8. Using the ALSB Admin Console, select the Security Configuration section, and select Access Control. For the proxy service (EchoProxyService), select View Policies for "Transport Authorization Policy" and add a single new condition for "Allow access to everyone," and then select View Policies for "Service Authorization Policy" and add a single new condition for "User bob." This configuration specifies that anyone can use HTTP/HTTPS to connect to the proxy service URL (useful to enable the WSDL for the service to be viewed by anyone), but only user "bob" (and therefore not "alice") can run the Web service's operations.

9. To test that the access control works, run the test client again. The service should be successfully called using the certificate for "bob," and the following message should be printed to the console by the client application:

Service result is: Hello from the client application

10. In the source code for the test client, replace the name of the key pair alias from "bob" to "alice," recompile the client, and run it again. This time the invocation of the ALSB proxy service should result in a SOAP fault being received by the client application specifying that access control failed. An error message similar to the following should be displayed:

Unable to invoke service: SOAPFaultException FaultCode
http://schemas.xmlsoap.org/soap/envelope/}Server] FaultString  
  [BEA-386000: com.bea.wli.sb.security.AccessNotAllowedException: 
    
                         access not allowed for subject Subject:
Principal = class weblogic.security.principal.WLSUserImpl("alice")
                      

Summary

This tutorial has shown how a Web service can be secured to enforce client applications to sign Web service requests and provide trusted certificates. Simply by modifying the security policy specified in the service's WSDL file, the security for the service can be easily changed to also enforce message encryption for Web service requests and both message signing and encryption for responses. Applying such security within an enterprise service bus, rather than within each of the "backend" business service message producers, provides these benefits:

  • All business services can be secured in the same way, even if some of the technologies used to create and provide some of these Web services don't actually support WS-Security or even a more basic security mechanism or protocol.
  • The same business service can be exposed with varying security policies and protocols (for example, basic authentication with HTTP, HTTPS/SSL, WS-Security) to support a mix of different types of clients. Such client applications may only have the technology to deal with one type of security protocol. Also, it may be a requirement to mandate different security policies for different types of message consumers for the same set of business services (for instance, another department interacting in the same local area network, or remote parts of a company interacting over the Internet, B2B, and e-commerce). For a single business service, multiple security policies can be defined to support different client applications by defining a different ALSB service proxy for each policy, and routing all these proxy services to the same "backend" business service.
  • Unlike transport-based security, WS-Security enables a message broker to make Web service routing decisions by inspecting some or all of the unencrypted SOAP message headers without having to decrypt the whole message.

A service bus provides a powerful way for an organization to declare and enforce its service security policies centrally, without requiring individual developers to hard-code security policy logic across all developed Web services and subsystems in a consistent manner.

References

Paul Done is a BEA Consultant based in the UK. Still a coder at heart, Paul likes the mix of high-level architecture and low-level technical problem solving which comes with the job.