Chapter 27. JAX-RPC Web Service Security

Table of Contents

27.1. Overview
27.2. Transport-Level Security
27.3. Message-Level Security
27.3.1. Applying Web Service Security
27.3.2. Web Service Security Architecture
27.3.3. Configuring JEUS Web Service Security
27.3.4. Creating a Password Callback Class
27.3.5. Example of Server-side JEUS Web Service Security
27.3.6. Example of Client-side JEUS Web Service Security
27.3.7. Creating JEUS Web Service Client Using Web Service Security API
27.4. Configuring Access Control
27.4.1. Configuring Access Control Security for Java Web Services
27.4.2. Configuring Access Control for EJB Web Services
27.4.3. Invoking Web Services Configured with Basic Authentication

This chapter describes how to configure security for JAX-RPC Web services.

27.1. Overview

There are two main security types for Web services.

  • Transport-level Security

    Maintains SSL security for connections between clients and Web services.

    With transport-level security, you can secure the connection between the client application and JEUS Server by using the Secure Sockets Layer (SSL) protocol. However, this only secures the connection itself. If there are any intermediaries between the client and JEUS Server, such as a router or message queue, the intermediaries get the SOAP message as a plain text that is not encrypted. Also, transport-level security is "all or nothing" which means either the entire SOAP message is encrypted or it is not encrypted at all. There is no way to specify only selected parts of the SOAP message to be encrypted.

  • Message-level security

    Digitally signs or encrypts SOAP messages.

    Message-level security includes all the security benefits of SSL, and also provides additional flexibility and features. Message-level security is end-to-end, which means that a SOAP message is secure even when the transmission involves one or more intermediaries. The SOAP message itself is digitally signed and encrypted, rather than relying on the security of the connection. In addition, parts of the message can be specified for signature or encryption.

27.2. Transport-Level Security

Transport-level security of JEUS web services is used to secure the connection between the client application and web server by using the Secure Sockets Layer (SSL) protocol.

The following are the steps for transport-level security.

  1. Configure SSL for JEUS server.

    There are no additional settings required for JEUS web service development. Refer to "JEUS Web Engine Guide" for information about the SSL configuration on a JEUS server.

  2. Configure SSL for a client application using these steps.

    1. Obtain the digital certificates. (Save the certificates to a local directory via the Internet Explorer, etc.)

    2. Store the certificates in the Keystore.

    3. Configure the following system properties in order to create stubs from WSDL by using wsdl2java or execute a client to invoke the web service.

      –Djavax.net.ssl.trustStore=keystore_name
      –Djavax.net.ssl.trustStorePassword=keystore_password
    4. To use the wsdl2java console tool instead of ANT, configure the environment variables as in the following.

      set WSDL2JAVA_OPTS=-Djavax.net.ssl.trustStore=keystore_name 
            -Djavax.net.ssl.trustStorePassword=keystore_password

27.3. Message-Level Security

Message-level security ensures that the SOAP messages between a web service and a client, which calls the service, to be digitally signed or encrypted, or both.

JEUS web services support the following OASIS Standard 1.0 web Services Security.

  • OASIS Standard 1.0

    • SOAP Message Security V1.0

    • Username Token Profile V1.0

    • X.509 Token Profile V1.0

These standards define requirements for authentication, authorization, data integrity, and confidentiality to help resolve many security issues in enterprise applications.

27.3.1. Applying Web Service Security

Security for JEUS web services can be applied in the following ways.

  • A client can use an X.509 certificate to sign and encrypt a SOAP message, and invoke a security-enabled web service. The web service can send a response by encrypting and signing the SOAP message by using the X.509 certificate. Since the SOAP message itself contains all the security information, intermediaries between the client application and web service can choose to only process the desired parts of the message.

  • By default, when a user does not specify a particular part for encryption, JEUS web service encrypts only the SOAP message body, but any parts of the message can be encrypted or signed, or both.

27.3.2. Web Service Security Architecture

The following shows the JEUS Web service security architecture.

[Figure 27.1] JEUS Web Service Security Architecture

JEUS Web Service Security Architecture

The server keystore is configured in the jeus-webservices-dd.xml file, and the client keystore is configured in the jeus-web-dd.xml file.

Secure Message Communication Between JEUS JavaEE Web Service Client and JEUS Web Service

In order to apply security to a pre-existing web service, you must configure the <security> element of the jeus-webservices-dd.xml file and create a keystore. You must also create a callback class for setting the access password for the keystore or the password to use in a UsernameToken. JEUS server applies security to the web service when the application is redeployed.

Java EE client must also set the <security> element of the jeus-web-dd.xml file, and create a keystore for the client's key. A callback class must be created in order to set a password for the Username Token and one for obtaining a private key from the key store.

When a Java EE client application is executed, the web service client runtime applies security logic according to the value of the <security> element of the jeus-web-dd.xml file. The runtime sends the message to the web service runtime of JEUS Server by encrypting the message with a server-side public key or by signing with the private key from the client key store.

The server runtime performs security logic based on the value of the <security> element in the jeus-webservices-dd.xml file.

  • If the message is signed, the signature is authenticated by using the client-side public key from the key store based on the information about the key used to sign the message.

  • If the message is encrypted, the server runtime decrypts the message by using the client's private key from the server-side keystore.

Similar procedures are used to apply security when the server tries to send a response message back to the client after invoking a web service.

  • A Web service takes a server-side private key or a client-side public key from the key store, using the <security> element value, to sign or encrypt the whole or a part of a response message.

  • A client runtime uses the server-side public key or client-side private key from the client key store, also using the <security> element value, to verify and decrypt the response message.

Interoperability of Message Security between JEUS and Third Party Vendors

Message-level security is used for web services. Interoperability is guaranteed when the security related information included in a secure SOAP message conforms to the OASIS Standard 1.0 Web Service Security.

Since JEUS conforms to the web service security standard 1.0, the latest version of OASIS security standards, it is possible to exchange and process messages between any vendors conforming to the same standard.

27.3.3. Configuring JEUS Web Service Security

To exchange secure messages between a JEUS web service and JEUS web service client, the <security> element of the jeus-webservices-dd.xml file must be configured for the JEUS web service, and the <security> element of the jeus-web-dd.xml file must be configured for the JEUS web service client.

Configuring Server-Side Security

The <security> element in the jeus-webservices-dd.xml file is required for every web service port. For more information, refer to "24. jeus-webservices-dd.xml" of the "JEUS XML Reference".

The following is an example of the server-side security configurations.

[Example 27.1] <<jeus-webservices-dd.xml>>

<jeus-webservices-dd>
    <service>
        <webservice-description-name/>
        <port>
            <port-component-name/>
            <security>
                <request-receiver/> 
                <response-sender/>
            </security>
        </port>
    </service>
</jeus-webservices-dd>


The information required for the server to securely process the messages from the client must be set in the <request-receiver> element, a child element of the <security> element. The information required for the client to securely process the messages from the server must be set in the <request-sender> element.

Configuring Client-side Security

The <security> element added to the jeus-web-dd.xml file is required for every <port-info> element. For more information, refer to "19. jeus-web-dd.xml" of the "JEUS XML Reference".

The following is an example of the client-side security configurations.

[Example 27.2] <<jeus-web-dd.xml>>

<jeus-web-dd>
    <service-ref>
        <service-client>
            <service-ref-name/>
            <port-info>
                <wsdl-port/>
                <security>
                    <request-sender/>
                    <response-receiver/>
                </security>
            </port-info>
            . . .
        </service-client>
        <service-client>
            . . .
        </service-client>
        . . .
    </service-ref>
</jeus-webservices-client-dd>


The <request-sender> element, which is a sub-element of the <security> element, specifies the information necessary for the server to handle secure messages requested by the client. The <response-receiver> element specifies the information necessary for the client to handle secure response messages from the server.

27.3.4. Creating a Password Callback Class

In order to apply security to JEUS web services, you must create a callback class for setting the access password for the keystore or the password for use in a UsernameToken. The Callback class must implement the javax.security.auth.callback.CallbackHandler interface.

The following example shows how to implement a password callback class.

[Example 27.3] << PWCallback.java >>

package jeustest.webservices.wssec.doall;

import com.tmax.ws.security.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;

public class PWCallback implements CallbackHandler {
    public void handle(Callback[] callbacks)
        throws IOException, UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof WSPasswordCallback) {
                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
                checkPassword(pc);
            } else {
                throw new UnsupportedCallbackException(
                    callbacks[i], "Unrecognized Callback");
            }
        }
    }

    public void checkPassword(WSPasswordCallback pc) {
        String userId = pc.getIdentifier();
        if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN) {
            if (userId.equals("16c73ab6-b892-458f-abf5-2f875f74882e")) {
                pc.setPassword("security2");
            }
            if (userId.equals("key_tmax1")) {
                pc.setPassword("keypass_tmax1");
            }
        } else if (pc.getUsage() == WSPasswordCallback.DECRYPT) {
            if (userId.equals("16c73ab6-b892-458f-abf5-2f875f74882e")) {
                pc.setPassword("security");
            }
            if (userId.equals("key_tmax1")) {
                pc.setPassword("keypass_tmax1");
            } 
        } else if(pc.getUsage() == WSPasswordCallback.SIGNATURE) {
            if (userId.equals("16c73ab6-b892-458f-abf5-2f875f74882e")) {
                pc.setPassword("security");
            }
            if (userId.equals("key_tmax1")) {
                pc.setPassword("keypass_tmax1");
            }
        }
    }
}


The WSPasswordCallback.getUsage() method returns a value that specifies when to use the callback parameter. If the parameter is used for setting a password in the UsernameToken, it returns the value 'USERNAME_TOKEN'. If it is used for setting a password to decrypt a secure message, it returns the value 'DECRYPT'. These implementations are also required to set a password for obtaining a private key for a signature from the key store or for configuring a session key.

The name of a callback class must be specified in the <password-callback-class> element of the jeus-webservices-dd.xml or jeus-web-dd.xml file.

27.3.5. Example of Server-side JEUS Web Service Security

A secure web service that sends/receives a string message is implemented in the following steps.

  1. Create a keystore that is required for encrypting and applying digital signature to a SOAP message.

  2. Create a Java class.

  3. Configure the DD.

  4. Complete packaging and deployment.

This section describes each step.

27.3.5.1. Creating a Keystore

A pair of keys are required to encrypt and apply digital signature to a SOAP message. This can be easily implemented by using the keytool provided in Java. There are many other methods besides keytool, but this section uses the keytool as an example. For more information, refer to the help for keytool.

Execute 'keygen' from the directory with the sample files.

  1. Create a keystore file called 'server-keystore.jks' and set the password to 'keystore_password'. Then create a private key (with an alias of 'JEUS_SERVER') by using the RSA algorithm. The password for the private key is 'key_password'. A pair of public keys for the 'JEUS_SERVER' private key is also automatically created.

    keytool -genkey -alias JEUS_SERVER -keyalg rsa -keypass
    key_password -keystore server-keystore.jks -storepass
    keystore_password
  2. Create a keystore file called 'client-keystore.jks' and set the password to 'keystore_password'. Then create a private key (with an alias of 'JEUS_CLIENT') by using the RSA algorithm. The password for the private key is ‘key_password’. A pair of public keys for the 'JEUS_CLIENT' private key is also automatically created.

    keytool -genkey -alias JEUS_CLIENT -keyalg rsa -keypass
    key_password -keystore client-keystore.jks -storepass
    keystore_password
  3. Obtain the 'JEUS_SERVER' public key from the 'server-keystore.jks' file, which will be used as the server-side keystore.

    $ keytool -export -alias JEUS_SERVER -storepass keystore_password
    -keystore server-keystore.jks -file jeus_server.cert
  4. Save it in the 'client-keystore.jks' file (keystore for web service client) by using the alias, 'JEUS_SERVER'.

    $ keytool -import -file jeus_server.cert -keystore
    client-keystore.jks -storepass keystore_password -alias JEUS_SERVER
  5. Obtain the 'JEUS_CLIENT' public key from the 'client-keystore.jks' file, which will be used as the client-side keystore.

    $ keytool -export -alias JEUS_CLIENT -storepass keystore_password
    -keystore client-keystore.jks -file jeus_client.cert
  6. Save it in the 'server-keystore.jks' file (keystore for web service) by using the alias, 'JEUS_CLIENT'.

    $ keytool -import -file jeus_client.cert -keystore
    server-keystore.jks -storepass keystore_password -alias JEUS_CLIENT

27.3.5.2. Creating a Java Class

The basic implementation of a secure web service is identical to that of a non-secure web service.

[Example 27.4] << Ping.java >>

package ping;

public interface Ping extends java.rmi.Remote {
    public String ping(String arg) throws
        java.rmi.RemoteException;
}


[Example 27.5] << PingImpl.java >>

package ping;

public class PingImpl implements Ping {
    public String ping(String arg) throws
        java.rmi.RemoteException {
        return arg;
    }
}


For secure web services, a callback class is required to set a password for the Username Token or to obtain a private key.

[Example 27.6] << PingPWCallback.java >>

package ping;

import com.tmax.ws.security.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;

public class PingPWCallback implements CallbackHandler {
    public void handle(Callback[] callbacks) throws
        IOException, UnsupportedCallbackException {
        for ( int i = 0 ; i<callbacks.length; i++) {
            if(callbacks[i] instanceof WSPasswordCallback) {
                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

                if(pc.getUsage()== WSPasswordCallback.USERNAME_TOKEN) {
                    pc.setPassword("usertoken_password");
                }

                if(pc.getUsage()== WSPasswordCallback.DECRYPT){
                    pc.setPassword("key_password");
                }

                if(pc.getUsage()== WSPasswordCallback.SIGNATURE) {
                    pc.setPassword("key_password");
                }
            }
        }
    }
}


27.3.5.3. Configuring a DD File

Create a web service DD after creating a keystore and implementing a Java class. Other DD configurations are same as those for non-secure web services, but additional configurations are required in the jeus-webservices- dd.xml file.

The following example shows the configurations used for handling client messages from the server. Refer to the sample for the complete file.

[Example 27.7] << jeus-webservices-dd.xml >>

. . .
<security>
    <request-receiver>
        <action-list>
            UsernameToken Signature Encrypt
        </action-list>
        <password-callback-class>
            ping.PingPWCallback
        </password-callback-class>
        <decryption>
            <keystore>
                <key-type>jks</key-type>
                <keystore-password>
                    keystore_password
                </keystore-password>
                <keystore-filename>
                    server-keystore.jks
                </keystore-filename>
            </keystore>
        </decryption>
        <signature-verification>
            <keystore>
                <key-type>jks</key-type>
                <keystore-password>
                    keystore_password
                </keystore-password>
                <keystore-filename>
                    server-keystore.jks
                </keystore-filename>
            </keystore>
        </signature-verification>
    </request-receiver>
    . . .
</security>
. . .


27.3.5.4. Packaging and Deployment

The packaging and deployment of a secure web service is similar to that of a non-secure web service, except that the keystore (server-keystore.jks) must reside in the class path of the context. The file name can also be configured by using the absolute path of the keystore in the <keystore-filename> element of the jeus-webservices-dd.xml file.

Entering the following from the sample's home directory, named 'pingSecurityService', completes the packaging and deployment of the modules to JEUS Server.

ant

Now, the secure web service is ready to be executed.

27.3.6. Example of Client-side JEUS Web Service Security

The client example is very similar to the server example. The tasks for the callback class, configuration file, and keystore packaging are required in addition to the normal task of creating a web service client.

A client-side JEUS web service security is implemented in the following steps.

  1. Create a keystore that is required for encrypting and applying digital signature to a SOAP message.

  2. Create a Java class.

  3. Configure the DD.

  4. Complete packaging and deployment.

This section describes each step.

27.3.6.1. Creating a Keystore

Use the 'client-keystore.jks' from the keystores created in the"27.3.5.1. Creating a Keystore" section.

27.3.6.2. Creating a Java Class

The following code is from the 'pingClient.jsp' file. Since the web service security is applied at the web service port-level, the port name that will be used must be specified.

[Example 27.8] << pingClient.jsp >>

. . . 
InitialContext jndiContext = new InitialContext();

Service service = (Service)jndiContext.lookup(
"java:comp/env/service/PingSecurityService");

QName portName = new QName("urn:PingSecurityService","PingPort");
java.rmi.Remote port = service.getPort(portName, Ping.class);

Ping pingPort = (Ping)port;
ret = pingPort.ping(msgToSend);
. . .


A callback class must be created for the clients, and the callback class created on the server-side can be reused for this.

27.3.6.3. Configuring a DD File

Other configuration files are created in the same way as the web service client DD files for non-secure web services, but additional configurations are required in the 'jeus-web-dd.xml'.

The following example shows the configurations used for handling request messages from the client. Refer to the sample for the complete file.

[Example 27.9] << jeus-web-dd.xml >>

. . .
<security>
    <request-sender>
        <action-list>
            UsernameToken Signature Encrypt
        </action-list>
        <password-callback-class>
            ping.PingPWCallback
        </password-callback-class>
        <user>JEUS_CLIENT</user>
        <signature-infos>
            <signature-info>
                <keyIdentifier>DirectReference</keyIdentifier>
                <keystore>
                    <key-type>jks</key-type>
                    <keystore-password>
                        keystore_password
                    </keystore-password>
                    <keystore-filename>
                        client-keystore.jks
                    </keystore-filename>
                </keystore>
            </signature-info>
        </signature-infos>
        <encryption-infos>
            <encryption-info>
                <encryptionUser>JEUS_SERVER</encryptionUser>
                <keyIdentifier>DirectReference</keyIdentifier>
                <keystore>
                    <key-type>jks</key-type>
                    <keystore-password>
                        keystore_password
                    </keystore-password>
                    <keystore-filename>
                        client-keystore.jks
                    </keystore-filename>
                </keystore>
            </encryption-info>
        </encryption-infos>
    </request-sender>
    . . .
</security>
. . .


27.3.6.4. Packaging and Deployment

The packaging and deployment of a secure web service client is similar to that of a non-secure web service client, except that the keystore (client-keystore.jks) must reside in the class path of the context. The file name can also be configured by using the absolute path of the keystore in the <keystorefilename> element of the jeus-web-dd.xml file.

Entering the following from the sample's home directory, named 'pingSecurityServiceJavaeeClient', the packaging and deployment of the modules to JEUS Server.

ant

Now, the secure web service client is ready to be executed.

27.3.7. Creating JEUS Web Service Client Using Web Service Security API

JEUS web services provide the Web Service Security API that enables easy creation of web service clients for both Java EE and Java SE environments.

The following example shows a secure web service client that uses the API.

[Example 27.10] << pingClient.jsp >>

<%@ page language="java" %>
<%@ page import="javax.naming.*" %>
<%@ page import="javax.rmi.*" %>
<%@ page import="java.rmi.RemoteException" %>
<%@ page import="java.util.*" %>

<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.xml.rpc.Service" %>
<%@ page import="javax.xml.namespace.QName" %>

<%@ page import="jeus.webservices.wssecurity.SecurityConfiguration"%>
<%@ page import="jeus.webservices.wssecurity.Keystore" %>

<%@ page import="ping.*" %>
<%@ page errorPage="/error.html" %>

<%! String msgToSend = "msg_sent_by_jspClient";
    String ret=null;
    String exceptionString="";
%>

<%
    try {
(1)     Keystore keystore = new Keystore ("JKS", "keystore_password", 
                           "client-keystore.jks");
        Keystore truststore = new Keystore ("JKS","keystore_password", 
                           "client-keystore.jks");

        InitialContext jndiContext = new InitialContext();
            
        Service service = 
          (Service)jndiContext.lookup("java:comp/env/service/PingSecurityService");
        QName portName = new QName("urn:PingSecurityService", "PingPort");

(2)     SecurityConfiguration sconfig = 
            new SecurityConfiguration(service, portName);
(3)     sconfig.setUsername("JEUS_CLIENT");
(4)     sconfig.setRequestPasswordCallbackClass("ping.PingPWCallback");
            
(5)     sconfig.addUTRequest(true, true);
(6)     sconfig.addSignRequest(null, "DirectReference", keystore);
(7)     sconfig.addEncryptRequest(null, "DirectReference", 
            truststore, "JEUS_SERVER", null);

(4)     sconfig.setResponsePasswordCallbackClass("ping.PingPWCallback");
        sconfig.addUTResponse();
        sconfig.addSignResponse(truststore);
        sconfig.addDecryptResponse(keystore);

        java.rmi.Remote port = service.getPort(portName, Ping.class);
        Ping pingPort = (Ping)port;
            
        ((javax.xml.rpc.Stub)pingPort)._setProperty(
            javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY,
            "http://localhost:8088/PingSecurity" + "/PingSecurityService");
            
        System.out.println("Send : " + msgToSend);
        ret = pingPort.ping(msgToSend);
        System.out.println("You received : " + ret);
    } catch (Exception e) {
        exceptionString = e.toString();
        e.printStackTrace();
    }
%>
<%= "Result is " + ret + "......" 
%>
<%= exceptionString
%>


The text in bold represents the configurations related to the web service security. The jeus.webservices.wssecurity.SecurityConfiguration object must be instantiated for security configurations, and the user name and password callback class must be specified to create a secure request message. For information about instantiating a callback class object, refer to "27.3.4. Creating a Password Callback Class".

The provided API can be used to add any configurations related to the username token, encryption, or digital signature. The jeus.webservices.wssecurity.Keystore class can be instantiated to configure the keystore settings.

  • (1) Instantiating Keystore Object

    To apply the web service security API, the keystore object must be instantiated for digital signature and encryption.

    public Keystore(String keyType, String keystorePassword, String keystoreFilename)
    ParameterDescription
    keystoreFilenameKeystore file name.
    keystorePasswordKeystore password.
    keyTypeKey type stored in the keystore. The supported key type is either "JKS" or "PKCS12".
  • (2) Instantiating Security Configuration Object

    This is the first object that needs to be instantiated in order to apply the web service security API.

    public SecurityConfiguration(javax.xml.rpc.Service service,QName portName) 
              throws ConfigurationException
    ParameterDescription
    serviceWhen creating a Java EE web service client, use the Service object obtained from JNDI as the service parameter. For a Java SE web service client, use the object instantiated with Service_Impl() as the service parameter.
    portNameUse the QName specified in WSDL as portName parameter.
  • (3) Setting Username

    Creating a secure web service request message requires a name for the username token or a private key name for the signature. The following method is used to set the name.

    public void setUsername(String username)
  • (4) Setting Callback Class Name

    To exchange a secure web service request or response message, password callback classes must be created to set the password for a username token or a private key. Configure the callback class name by using the following methods.

    public void setRequestPasswordCallbackClass(String classname)
    public void setResponsePasswordCallbackClass(String classname)
  • (5) Processing UsernameToken

    Use this method to add the UsernameToken element to a request message.

    public void addUTRequest(boolean addNonceCreated, boolean passwordDigest)

    A password can be in a text or digest format. If it is in the text format, you can choose whether to include the Nonce and Created elements.

    Use the following method when the secure response message is expected to include the Username Token element.

    public void addUTResonse()
  • (6) Processing Digital Signature

    Use this method to digitally sign a specific part of a request message.

    public void addSignRequest(QName signPart, String keyIdentifier, 
                           Keystore keystore)
           throws SecurityConfigurationException
    ParameterDescription
    signPartIf set to null, the signature is added to the SOAP message body.
    keyIdentifier

    Set to one of:

    • IssuerSerial

    • DirectReference

    • SKIKeyIdentifier

    • X509KeyIdentifier

    keystoreKeystore object that contains the private key used for the signature.
  • (7) Processing Encryption

    Use this method to encrypt a specific part of the request message.

    public void addEncryptRequest(QName encPart, String keyIdentifier,
        Keystore keystore, String encryptUser, String algorithm)
        throws SecurityConfigurationException
    ParameterDescription
    encPart

    Part of the SOAP message to encrypt. Must be entered in the QName format. If set to null, the entire SOAP message body is encrypted.

    keyIdentifier

    Set to one of:

    • IssuerSerial

    • DirectReference

    • SKIKeyIdentifier

    • X509KeyIdentifier

    • EmbeddedKeyName

    keystoreKeystore object that contains the public key.
    encryptUserAlias for the public key used for encryption.
    algorithm

    Algorithm used for the encryption. Set to one of:

    • AES_128

    • AES_256

    • TRIPLE_DES

    • AES_192

    Use the following method to request an encryption of a specific part of the request message. This method is especially useful when a key is set as a byte array in a specific callback class, and the key needs to be called by its name.

    public void addEncryptRequest(QName encPart,
        String keyIdentifier, String embeddedKeyCallbackClass,
        String keyName, String encryptUser, String algorithm)

    Use the following method to request an encryption of a specific part of the response message. Use the keystore object that contains the private key for the encryption as the keystore parameter.

    public void addDecryptResponse(Keystore keystore)

[Reference]

The following are additional methods that are available for use but are not used in the examples of this chapter.

  • Processing TimeStamp

    Use the following method to add a TimeStamp element to a secure request message.

    public void addTimeStampRequest()

    Use the following method to set the message expiration period of a secure web service request message. By default, the period is set to 300 seconds.

    public void addTimeStampRequest(int timeToLive)

    Use the following method when the secure response message is expected to include the TimeStamp element.

    public void addTimeStampResponse()

    Only use the following method when the expiration date set in the TimeStamp element for the secure response message is within the time period specified by the argument.

    public void addTimeStampResponse(int timeToLive)

27.4. Configuring Access Control

Access control configuration can be set to only allow authorized users to call the web service. The access control configuration varies depending on the web service backends. This section describes how to set the web service access control, and how to call an access-controlled web service.

27.4.1. Configuring Access Control Security for Java Web Services

Web service access can be controlled by applying access control to the URL of the web service. In order to apply access control, security information has to be specified in the deployment descriptor files ('web.xml' and 'jeus-web-dd.xml'). A secure domain configuration is also required.

Configuring Secure Domain

First, a user must be registered to apply access control.

Register the user in the following file.

JEUS_HOME/config/{NODE_NAME}/security/{SECURITY_DOMAIN_NAME}/accounts.xml

The following is an example of registering a user with the username of "jeus" and password of "jeus". The password must be encrypted using Base64 encoding.

[Example 27.11] << accounts.xml >>

<accounts xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
    <users>
        <user>
            <name>jeus</name>
            <password>{SHA}McbQlyhI3yiOG1HGTg8DQVWkyhg=</password>
        </user>
    </users>
</accounts>


Configuring a DD File

Add the following <role-mapping> element to the jeus-web-dd.xml file.

[Example 27.12] << jeus-web-dd.xml >>

<jeus-web-dd xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
    <docbase>BA_DocLitEchoService</docbase>
    <role-mapping>
        <role-permission>
            <principal>jeus</principal>
            <role>Administrator</role>
        </role-permission>
    </role-mapping>
</jeus-web-dd>


Then add the following security related settings to the web.xml file.

[Example 27.13] << web.xml >>

<web-app…>
    . . .
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>MySecureBit</web-resource-name>
            <url-pattern>/BA_DocLitEchoService</url-pattern>
            <http-method>POST</http-method>
            <http-method>GET</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>Administrator</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>   
    
    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>default</realm-name>
    </login-config>    
</web-app>


When the previous setting is applied, only the user with the username "jeus" and password "jeus" can access the URL, '/BA_DocLitEchoService'.

27.4.2. Configuring Access Control for EJB Web Services

Similar to a Java web service, the access to an EJB web service can be controlled by applying access control to the web service URL. In order to apply access control, security information has to be specified in the deployment descriptor files ('ejb-jar.xml' and 'jeus-ejb-dd.xml') and the web service deployment descriptor file ('jeus-webservices-dd.xml'). A secure domain configuration is also required.

Configuring Secure Domain

First, a user must be registered to apply access control.

Register the user in the following file.

JEUS_HOME/config/{NODE_NAME}/security/{SECURITY_DOMAIN_NAME}/accounts.xml

The following is an example of registering a user with the username of "jeus" and password of "jeus". The password must be encrypted using Base64 encoding.

[Example 27.14] << accounts.xml >>

<accounts xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
    <users>
        <user>
            <name>jeus</name>
            <password>{SHA}McbQlyhI3yiOG1HGTg8DQVWkyhg=</password>
        </user>
    </users>
</accounts>


Configuring a DD file

Add the following <role-permission> element to the jeus-ejb-dd.xml file.

[Example 27.15] << jeus-ejb-dd.xml >>

<jeus-ejb-dd xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
    <module-info>        
        <role-permission>
            <principal>jeus</principal>
            <role>Administrator</role>
        </role-permission>
    </module-info>
    <beanlist>
        …
    </beanlist>
</jeus-ejb-dd>


Then add the following security related settings to the ejb-jar.xml file.

[Example 27.16] << ejb-jar.xml >>

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar …>
    <display-name>AddressEjb</display-name>
    <enterprise-beans>
        …
    </enterprise-beans>
    <assembly-descriptor>
        <security-role>
            <role-name>Administrator</role-name>
        </security-role>
        <method-permission>
            <role-name>Administrator</role-name>
            <method>
                <ejb-name>AddressEJB</ejb-name>
                <method-intf>ServiceEndpoint</method-intf>
                <method-name>listAll</method-name>                
            </method>
        </method-permission>
    </assembly-descriptor>
</ejb-jar>


The following configurations can be additionally set in the web service deployment descriptor. Default values are used if they are not configured. In order to guarantee the data integrity of SSL socket communication, the <ejb-transport-guarantee> must be set to 'INTEGRAL'. If both the confidentiality and data integrity must be guaranteed, set it to 'CONFIDENTIAL'. A separate HTTP listener configuration is also required to enable HTTPS communication.

[Example 27.17] << jeus-webservices-dd.xml >>

<jeus-webservices-dd xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
    <ejb-context-path>webservice</ejb-context-path>
    <ejb-login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>default</realm-name>
    </ejb-login-config>
    <service>
        <webservice-description-name>…</webservice-description-name>
        <port>
            <port-component-name>…</port-component-name>
            <ejb-endpoint-url>… </ejb-endpoint-url>
            <ejb-transport-guarantee>
                CONFIDENTIAL
            </ejb-transport-guarantee>
        </port>
    </service>
</jeus-webservices-dd>


27.4.3. Invoking Web Services Configured with Basic Authentication

In order to invoke a web service that is configured with basic authentication, a stub must be generated based on the information from the WSDL. The stub is used to call the web service, and in case a username and password are required they must also be configured.

Creating a Stub from WSDL

When using a console tool, use the following options.

wsdl2java -gen:client -username jeus -password jeus 
http://localhost:8088/BA_DocLitEchoService/BA_DocLitEchoService?wsdl

Creating Web Service Clients for a Web Service Configured with Basic Authentication

The following two configurations must be included in the client application to allow a JAX-RPC web service client to authenticate itself.

  • javax.xml.rpc.Stub.USERNAME_PROPERTY

  • javax.xml.rpc.Stub.PASSWORD_PROPERTY

The following example shows how to include the configurations in a client program.

Echo port = // … obtaining SEI
((javax.xml.rpc.Stub) port)._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, 
      "jeus");
((javax.xml.rpc.Stub) port)._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, 
      "jeus");
String s = port.echoString("JEUS");