A common implementation model for Oracle Documaker Standard Edition ("ODSE") includes enabling interoperability with API and other interfaces such as enterprise service busses. For such requirements, Oracle includes Enterprise Web Processing Services ("EWPS") as part of ODSE, which is a set of SOAP 1.1- and SOAP 1.2-compliant web services that perform common functions such as submitting requests to Docupresentment ("IDS") that result in print output such as PDFs. Business or Technical requirements may stipulate that web service security is required.

Types of Web Service Security

Tomcat supports several types of security which can be applied to EWPS. In this document, we'll cover:

  • transport-layer security, which prevents inspection or alteration of messages exchanged between the service and the service consumer (aka "encryption", "SSL", or "HTTPS");
  • role-base access control (RBAC) restricts access to resources based on the roles assigned to users. This mechanism helps in defining and enforcing security policies, ensuring that only authorized users can access certain parts of a web application.
  • network-layer security, which prevents access based on client IP address.

Transport Layer Security

Transport Layer Security (TLS) is a cryptographic protocol designed to provide secure communication over a computer network. TLS ensures that the data sent between a client (like a web browser) and a server (like a website) is encrypted, authenticated, and remains private and integral. Here’s a breakdown of its key components and how it works:

Key Components of TLS

  • Encryption: TLS uses encryption to protect data as it travels across the network, making it unreadable to anyone who might intercept it. Common encryption algorithms include AES (Advanced Encryption Standard).
  • Authentication: TLS ensures that the parties involved in the communication are who they claim to be. This is typically achieved through the use of certificates issued by trusted Certificate Authorities (CAs).
  • Integrity: TLS guarantees that the data has not been tampered with during transit. It uses hash functions (like SHA) to create a unique fingerprint for the data, which helps in detecting any alterations.

How TLS Works

  • Handshake Process: The communication starts with a TLS handshake. During this process, the client and server exchange cryptographic keys and agree on the encryption methods to use.
  • Certificates and Keys: The server presents its digital certificate to the client, which includes the server’s public key. The client verifies this certificate with a trusted CA.
  • Session Keys: Once the certificate is verified, the client and server use the public key to generate a shared session key, which is used to encrypt and decrypt the data during the session.
  • Data Transfer: After the handshake, data is transferred using the agreed-upon encryption method. The session key ensures that the data remains confidential and integral.

Identity certificates, Certificate Authorities (CAs), and root certificates work together to establish secure communications by verifying the identities of the parties involved. Here’s how they function in one-way and two-way authentication models.

Server Authentication (One-Way SSL)

In one-way authentication, only the server is authenticated by the client. This is the most common scenario for web applications, where the client needs to ensure that it is communicating with a legitimate server.

  1. Server Certificate: The server presents its identity certificate to the client. This certificate contains the server’s public key and is issued by a trusted CA.
  2. Certificate Authority (CA): The CA is a trusted third party that issues certificates. The CA verifies the identity of the server before issuing the certificate. The CA’s own certificate is trusted by clients and is usually pre-installed in browsers and operating systems.
  3. Root Certificate: The root certificate is the top-level certificate in the CA hierarchy. It is self-signed and trusted by the client. Intermediate certificates, if any, link the server certificate to the root certificate in a chain of trust.
  4. Handshake Process:
    1. The client initiates a connection to the server.
    2. The server responds by sending its certificate.
    3. The client verifies the server’s certificate by checking the chain of trust up to the root certificate.
    4. If the verification is successful, the client generates a session key and encrypts it with the server’s public key.
    5. The server decrypts the session key with its private key.
    6. Both parties use the session key to encrypt and decrypt data during the session.

Mutual Authentication (Two-Way SSL)

In mutual authentication, both the client and the server authenticate each other. This is commonly used in environments where both parties need to trust each other, such as B2B communications or sensitive transactions.

  1. Server Certificate: As in server authentication, the server presents its identity certificate to the client.
  2. Client Certificate: The client also presents its identity certificate to the server. This certificate is issued by a CA that is trusted by the server.
  3. Certificate Authority (CA): Both the client and server certificates are issued by CAs. Each party must trust the CA that issued the other’s certificate.
  4. Root Certificates: Both the client and server must have the root certificates of the CAs that issued each other’s certificates.
  5. Handshake Process:
    1. The client initiates a connection to the server.
    2. The server sends its certificate to the client.
    3. The client verifies the server’s certificate.
    4. If the server’s certificate is verified, the client sends its certificate to the server.
    5. The server verifies the client’s certificate.
    6. If both verifications are successful, the client and server exchange session keys encrypted with each other’s public keys.
    7. Both parties use the session key to encrypt and decrypt data during the session.

Certificate Verification

Each certificate (server or client) is part of a chain that leads back to a root certificate. Intermediate certificates link the end-entity certificate to the root certificate. Clients and servers have a trust store, a repository of trusted root certificates. They use this store to verify the certificate chain. Certificates can be revoked if compromised. Clients check the revocation status of certificates using mechanisms like Certificate Revocation Lists (CRLs) or the Online Certificate Status Protocol (OCSP).

Role-Based Access Control (RBAC)

Roles are named permissions that define what actions a user can perform. Roles are typically defined in a web application’s deployment descriptor (web.xml) so that each application can have its own set of defined roles. Individual user accounts can be assigned one or more roles. Users are defined in a realm – a database of users, passwords, and roles. Tomcat supports multiple types of realms, such as JDBC, JNDI, and memory-based realms (that are usually configured via a file). Finally, there are security constraints which define the access control rules for specific URL patterns in the web application.

Network Layer Security

This type of security manages the logical addressing and routing of requests by using firewalls, IPsec, anti-spoofing measures, and secure routing protocols. Inside Tomcat, we can provide further security by refusing access based on client address.

Certificates

Self-Signed Certificates

Using self-signed certificates is only appropriate for development or testing of internally-facing services and does not provide true security. Most client processes will complain about self-signed certificates since self-signed certificates are not tied to a CA certificate that exists in a trust store. In such cases, test and development environments are typically configured with inadequate security settings that allow for testing with self-signed certificates. As this presents a security risk (if such insecure settings make it into production), an organization may establish their own internal CA to issue their own certificates for internally-facing services. This is a significantly more complex configuration as it requires creation and maintenance of procedures for issuing certificates as well as maintaining and distributing trust stores to all clients, and following alternative procedures for establishing client and server identities. This type of configuration is outside the scope of this document.

To generate a self-signed certificate, use the keytool component of the Java Development Kit (JDK) that you're using to run Tomcat:

keytool -genkey -alias tomcat -keyalg RSA -keystore keystore.jks -keysize 2048

The alias value should always be tomcat. The keystore value should be a file that is accessible by the user that runs the tomcat process. You will be prompted to enter a keystore password and provide information for the certificate (such as your name, organization, etc.). Remember the keystore password as you’ll need it later.

Identity Certificates from a CA

If you have obtained an identity certificate from a CA, you can import it into your keystore using the keytool component of the Java Development Kit (JDK) that you're using to run Tomcat. Remember also to import any intermediary certificates that might be needed. Replace the keystore.jks with the path/filename of your keystore.

keytool -import -alias tomcat -file your_domain_certificate.crt -keystore keystore.jks
keytool -import -alias intermediate -file intermediate_certificate.crt -keystore keystore.jks

Server Authentication

To implement server authentication with Tomcat, you must first create or obtain an identity certificate using one of the methods described above. Then, modify the Tomcat server configuration file TOMCAT_HOME/conf/server.xml to point to the keystore where the identity certificate is stored. Add the following section, updating the location of the keystore and the password accordingly. Note that you can use the macro ${user.home} if you place the keystore in the home directory of the user that runs the Tomcat process. This is now the server's identity certificate.

<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" maxThreads="150"
   SSLEnabled="true">
  <SSLHostConfig>
    <Certificate
      certificateKeystoreFile="${user.home}/.keystore"
      certificateKeystorePassword="changeit"
      type="RSA"
      />
    </SSLHostConfig>
</Connector>

In order for this to work properly, your client processes must trust the identity certificate presented by the server. One way to accomplish this is to ensure the identity certificate is issued by a trusted CA (e.g. a CA whose root certificate is in the client trust store), or to import the identity certificate into the client trust store.

Mutual Authentication

To implement mutual authentication with Tomcat, complete the steps above for setting up server authentication. Then, modify the Tomcat server configuration file TOMCAT_HOME/conf/server.xml to point to the trust store where client identity certificate(s) are stored.

Add the following section, updating the location of the trust store and the password accordingly. Note that you can use the macro ${user.home} if you place the trust store in the home directory of the user that runs the Tomcat process.

<Connector
    protocol="org.apache.coyote.http11.Http11NioProtocol"
    port="8443"
    maxThreads="150"
    SSLEnabled="true">
  <SSLHostConfig>
    <Certificate
      certificateKeystoreFile="${user.home}/.keystore"
      certificateKeystorePassword="changeit"
      truststoreFile="/path/to/server-truststore.jks"
      truststorePass="your_truststore_password"
      type="RSA"
      />
    </SSLHostConfig>
</Connector>

Finally, you will need to import client certificates into the server trust store using keytool. If you have multiple client certificates to import, you should use different aliases for each. As an alternative, if each client certificate is signed by a valid CA, you can import the CA's root certificate into the trust store rather than importing every client's certificate.

keytool -import -alias client -file client-cert.crt -keystore server-truststore.jks

Role-Based Access Control (RBAC)

First determine what kind of controls you need. In this example, we will simply control access to a protected resource by role. Create the role and define any users that will have the role in your security realm. In a default Tomcat installation, the memory-based security realm is defined by the conf/tomcat-users.xml file. Edit this file with a text editor. You will see that the default is no users — everything is commented out. You can add the following settings. Note that the actual role and user names are irrelevant as long as you maintain consistency. In the below example we create a sample user and role:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="ewps-user"/>
  <user username="myuser" password="mypassword" roles="ewps-user"/>
</tomcat-users>

Next, we can add the access control in the EWPS deployment descriptor file. This file is located within the WAR file so you'll need to explode the WAR file, or if you have already deployed it to Tomcat, you should see the directory webapps/ewps-axis2. Edit the WEB-INF/web.xml file with a test editor. There will be plenty of other details in this file so be careful not to modify other elements.

<web-app>
    ...
    <! -- define a role -->
    <security-role>
        <role-name>ewps-user</role-name>
    </security-role>
    ...
</web-app>

With the role now defined we can add access controls to the deployment descriptor. This generally means securing a URL by pattern as shown below. Here, we have defined a URL pattern and associated that pattern to a role.

<web-app>
    ...
    <! -- define an URL pattern and tie to role -->
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>EWPS Services</web-resource-name>
            <url-pattern>/ewps/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>ewps-user</role-name>
        </auth-constraint>
    </security-constraint>
    ...
</web-app>

Finally, we need to configure the authentication method. Typical methods are BASIC, DIGEST, or FORM. For web services, BASIC should be sufficient. Modify deployment descriptor file as shown:

<web-app>
    ...
    <! -- define the authentication method -->
    <login-config>
        <auth-method>BASIC</auth-method>
   </login-config>
    ...
</web-app>

Note that once you have done this (and restarted Tomcat) your client(s) will have to authenticate in order to process a request with EWPS. You can configure common testing tools with basic authentication, e.g. soapUI and Postman.

Optionally you can configure a realm to point to an external source such as a database via JDBC, LDAP repository, or JNDI service. There are many options available here – see Tomcat documentation for more details.  For example you can configure a JDBC realm by adding the following to the TOMCAT_DIR/conf/server.xml:

<Realm className="org.apache.catalina.realm.JDBCRealm"
  driverName="com.mysql.jdbc.Driver"
  connectionURL="jdbc:mysql://localhost:3306/mydatabase"
  connectionName="dbuser"
  connectionPassword="dbpassword"
  userTable="users"
  userNameCol="username"
  userCredCol="password"
  userRoleTable="user_roles"
  roleNameCol="rolename"/>

Another example of an LDAP-style realm:

<Realm className="org.apache.catalina.realm.JNDIRealm"
  connectionURL="ldap://localhost:10389"
  userPattern="uid={0},ou=users,dc=mycompany,dc=com"
  roleBase="ou=roles,dc=mycompany,dc=com"
  roleName="cn"
  roleSearch="(uniqueMember={0})"
  roleSubtree="true"/>

Once these changes are made, you can restart Tomcat.

Network Layer Security

In this example we will configure network layer security to restrict access by clients within a certain address space. This is done by modifying the TOMCAT_DIR/conf/server.xml file and adding a Valve element with appropriate allow or deny attributes:

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
...
    <Valve className="org.apache.catalina.valves.RemoteAddrValve"
           allow="192.168.1.100,192.168.1.101"
           deny="192.168.1.102"/>
...
</Host>

This configuration creates an allow list such that any client that does not match in the list (or pattern) will be denied. Similarly, any client that matches the deny list or pattern is explicitly denied. More complex patterns are possible using regular expressions, e.g.:

<Valve 
    className="org.apache.catalina.valves.RemoteAddrValve" 
    allow="^192\.168\.1\.\d{1,3}$" 
/>

The above example allows all IP addresses in the range 192.168.1.0 to 192.168.1.255, and excludes any others.

These settings apply to all applications hosted in Tomcat if they are applied in TOMCAT_DIR/conf/server.xml. Application-specific settings can be made in the WAR file's META-INF/context.xml file. For EWPS, you can again explode the WAR file or modify it in the filesystem after deployment. The file will need to be created as it is not provided with the default installer; note the presence of the <Context> node:

<Context>
    <Valve 
      className="org.apache.catalina.valves.RemoteAddrValve"
      allow="192.168.1.100,192.168.1.101"
      deny="192.168.1.102,192.168.1.103"
    />
</Context>

Hopefully this has given you more than enough information to get you on your way towards securing your EWPS deployment with Tomcat. As always you can leave questions/comments below or visit the Documaker community.

-A