8 Securing Oracle Coherence REST

This chapter provides instructions for securing Oracle Coherence REST and does not include general instructions for using Oracle Coherence REST. For detailed information on using Oracle Coherence REST, see .

This chapter includes the following sections:

8.1 Overview of Securing Oracle Coherence REST

Oracle Coherence REST security uses both authentication and authorization to restrict access to cluster resources. Authentication support includes: HTTP basic, client-side SSL certificate, and client-side SSL certificate together with HTTP basic. Authorization is implemented using Oracle Coherence*Extend-styled authorization, which relies on interceptor classes that provide fine-grained access for cache service and invocation service operations. Oracle Coherence REST authentication and authorization reuses much of the existing security capabilities of Oracle Coherence: references are provided to existing content where applicable.

Security for Oracle Coherence REST is disabled by default and is enabled as required. Authentication and authorization are configured separately. Authentication is configured in a cache configuration file using the <auth-method> element within the <http-acceptor> element. For details on the <auth-method> element, see the Developing Applications with Oracle Coherence. For detailed information about implementing authorization, see "Implementing Extend Client Authorization".

8.2 Using HTTP Basic Authentication with Oracle Coherence REST

HTTP basic authentication provides authentication using credentials (username and password) that are encoded and sent in the HTTP authorization request header. HTTP basic authentication requires a Java Authentication and Authorization Service (JAAS) login module as described in this section.

To specify basic authentication, add an <auth-method> element, within the http-acceptor element, that is set to basic.

<proxy-scheme>
   <service-name>RestHttpProxyService</service-name>
   <acceptor-config>
      <http-acceptor>
         ...
         <auth-method>basic</auth-method>
      </http-acceptor>
   </acceptor-config>
   <autostart>true</autostart>
</proxy-scheme>

8.2.1 Specify a Login Module

HTTP basic authentication requires a JAAS javax.security.auth.spi.LoginModule implementation that authenticates client credentials which are passed from the HTTP basic authentication header. The resulting Subject can then be used for both Oracle Coherence*Extend-style and Oracle Coherence Security Framework authorization as required. Refer to the JAAS Reference Guide for instructions about JAAS and creating a LoginModule implementation:

http://docs.oracle.com/javase/7/docs/technotes/guides/security/jaas/JAASRefGuide.html

To specify a login module, modify the COHERENCE_HOME/lib/security/login.config login configuration file and include a CoherenceREST entry that includes the login module implementation to use. For example:

CoherenceREST {
    package.MyLoginModule required debug=true;
};

At runtime, specify the login.config file to use either from the command line (using the java.security.auth.login.config system property) or in the Java security properties file. For details, see:

http://docs.oracle.com/javase/7/docs/technotes/guides/security/jaas/JAASLMDevGuide.html

As a convenience, a Java keystore (JKS) LoginModule implementation which depends only on standard Java run-time classes is provided. The class is located in the COHERENCE_HOME/lib/security/coherence-login.jar file. To use the implementation, either place this library in the proxy server classpath or in the JRE's lib/ext (standard extension) directory.

Specify the JKS login module implementation in the login.config configuration file as follows:

CoherenceREST {
    com.tangosol.security.KeystoreLogin required
      keyStorePath="${user.dir}${/}security${/}keystore.jks";
};

The entry contains a path to a keystore. Change the keyStorePath variable to the location of a keystore. For instructions about creating a keystore, see "Generating Java SSL Artifacts".

8.3 Using SSL Authentication With Oracle Coherence REST

SSL provides an authentication mechanism that relies on digital certificates and encryption keys to establish both identity and trust. For an overview of SSL, including generating SSL artifacts, see "Overview of SSL".

Client-side SSL certificates are passed to the HTTP acceptor to authenticate the client. SSL requires an SSL-based socket provider to be configured for the HTTP acceptor. The below instructions only describe how to configure SSL and define an SSL socket provider on the proxy for an HTTP acceptor. Refer to your REST client library documentation for instructions on setting up SSL on the client side.

To specify SSL authentication, add an <auth-method> element, within the http-acceptor element, that is set to cert.

<proxy-scheme>
   <service-name>RestHttpProxyService</service-name>
   <acceptor-config>
      <http-acceptor>
         ...
         <auth-method>cert</auth-method>
      </http-acceptor>
   </acceptor-config>
   <autostart>true</autostart>
</proxy-scheme>

8.3.1 Configure an HTTP Acceptor SSL Socket Provider

Configure an SSL socket provider for an HTTP acceptor when using SSL for authentication. To configure SSL for an HTTP acceptor, explicitly add an SSL socket provider definition or reference an SSL socket provider definition that is in the operational override file.

Explicitly Defining an SSL Socket Provider

To explicitly configure an SSL socket provider for an HTTP acceptor, add a <socket-provider> element within the <http-acceptor> element of each <proxy-scheme> definition. See Developing Applications with Oracle Coherence for a detailed reference of the <socket-provider> element.

Example 8-1 demonstrates configuring an SSL socket provider that uses the default values for the <protocol> and <algorithm> element (TLS and SunX509, respectively). These are shown for completeness but may be left out when using the default values.

Example 8-1 configures both an identity keystore (server.jks) and a trust keystore (trust.jks). This is typical of two-way SSL authentication, in which both the client and proxy must exchange digital certificates and confirm each other's identity. For one-way SSL authentication, the proxy server configuration must include an identity keystore but need not include a trust keystore.

Example 8-1 Sample HTTP Acceptor SSL Configuration

<proxy-scheme>
   <service-name>RestHttpProxyService</service-name>
   <acceptor-config>
      <http-acceptor>
         ...
         <socket-provider>
            <ssl>
               <protocol>TLS</protocol>
               <identity-manager>
                  <algorithm>SunX509</algorithm>
                  <key-store>
                     <url>file:server.jks</url>
                     <password>password</password>
                     <type>JKS</type>
                  </key-store>
                  <password>password</password>
               </identity-manager>
               <trust-manager>
                  <algorithm>SunX509</algorithm>
                  <key-store>
                     <url>file:trust.jks</url>
                     <password>password</password>
                     <type>JKS</type>
                  </key-store>
               </trust-manager>
            </ssl>
         </socket-provider>
         ...
         <auth-method>cert</auth-method>
      </http-acceptor>
   </acceptor-config>
   <autostart>true</autostart>
</proxy-scheme>

Referencing an SSL Socket Provider Definition

The following example references an SSL socket provider configuration that is defined in the <socket-providers> element of the operational deployment descriptor by specifying the id attribute (ssl) of the configuration. See Developing Applications with Oracle Coherence for a detailed reference of the <socket-providers> element.

Note:

A predefined SSL socket provider is included in the operational deployment descriptor and is named ssl. The predefined SSL socket provider is configured for two-way SSL connections and is based on peer trust, in which every trusted peer resides within a single JKS keystore. See "Using the Predefined SSL Socket Provider" for details. To configure a different SSL socket provider, use an operational override file to modify the predefined SSL socket provider or to create a socket provider configuration as required.

<proxy-scheme>
   <service-name>RestHttpProxyService</service-name>
   <acceptor-config>
      <http-acceptor>
         ...
         <socket-provider>ssl</socket-provider>
         ...
         <auth-method>cert</auth-method>
      </http-acceptor>
   </acceptor-config>
   <autostart>true</autostart>
</proxy-scheme>

8.3.2 Access Secured REST Services

The following example demonstrates a Jersey-based client that accesses REST services that require certificate and HTTP basic authentication. For details about creating Jersey clients, see http://jersey.java.net/nonav/documentation/latest/index.html.

Client SSL Configuration File

The client SSL configuration file (ssl.xml) configures the client's keystore and trust keystore.

<ssl>
  <identity-manager>
    <key-store>
      <url>file:keystore.jks</url>
      <password>password</password>
    </key-store>
    <password>password</password>
  </identity-manager>
  <trust-manager>
    <key-store>
      <url>file:trust.jks</url>
      <password>password</password>
    </key-store>
  </trust-manager>
</ssl>

Sample Jersey SSL Client

package example;
import com.oracle.common.net.SSLSocketProvider;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.client.urlconnection.HTTPSProperties;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import com.tangosol.internal.net.ssl.LegacyXmlSSLSocketProviderDependencies;
import com.tangosol.run.xml.XmlDocument;
import com.tangosol.run.xml.XmlHelper;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.ws.rs.core.MediaType;
 
public class SslExample
   {
   public static Client createHttpsClient(SSLSocketProvider provider)
      {
      DefaultClientConfig dcc = new DefaultClientConfig();
      HTTPSProperties prop = new HTTPSProperties(new HostnameVerifier()
         {
         public boolean verify(String s, SSLSession sslSession)
            {
               return true;
            }
         }, provider.getDependencies().getSSLContext());
      dcc.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, prop);
      return Client.create(dcc);
      }
 
   public static void PUT(String url, MediaType mediaType, String data)
      {
      process(url, "put", mediaType, data);
      }
 
   public static void GET(String url, MediaType mediaType)
      {
      process(url, "get", mediaType, null);
      }
 
   public static void POST(String url, MediaType mediaType, String data)
      {
      process(url, "post", mediaType, data);
      }
 
   public static void DELETE(String url, MediaType mediaType)
      {
      process(url, "delete", mediaType, null);
      }
 
   static void process(String url, String action, MediaType mediaType, String
      data)
      {
      try
         {
         XmlDocument xml = XmlHelper.loadFileOrResource("/ssl.xml", null);
         SSLSocketProvider provider = new SSLSocketProvider(new
            LegacyXmlSSLSocketProviderDependencies(xml));
         Client client = createHttpsClient(provider);
         ClientResponse response = null;
         WebResource webResource = client.resource(url);

         // If you've specified the "cert+basic" auth-method in your Proxy
         // http-acceptor configuration, initialize and add an HTTP basic
         // authentication filter by
         // uncommenting the following line and changing the username and password
         // appropriately.
         //client.addFilter(new HTTPBasicAuthFilter("username", "password"));

         if (action.equalsIgnoreCase("get"))
            {
            response = webResource.type(mediaType).get(ClientResponse.class);
            }
         else if (action.equalsIgnoreCase("post"))
            {
            response = webResource.type(mediaType).post
               (ClientResponse.class, data);
            }
         else if (action.equalsIgnoreCase("put"))
            {
            response = webResource.type(mediaType).put
               (ClientResponse.class, data);
            }
         else if (action.equalsIgnoreCase("delete"))
            {
            response = webResource.type(mediaType).delete
               (ClientResponse.class, data);
            }
         System.out.println("response status:" + response.getStatus());
         if (action.equals("get"))
            {
            System.out.println("Result: " + response.getEntity(String.class));
            }
         }
      catch (Exception e)
         {
         e.printStackTrace();
         }
      }
 
   public static void main(String args[])
      {
      PUT("https://localhost:8080/dist-http-example/1",
         MediaType.APPLICATION_JSON_TYPE, "{\"name\":\"chris\",\"age\":32}");
      PUT("https://localhost:8080/dist-http-example/2",
         MediaType.APPLICATION_XML_TYPE,
         "<person><name>admin</name><age>30</age></person>");
      DELETE("https://localhost:8080/dist-http-example/1",
         MediaType.APPLICATION_XML_TYPE);
      GET("https://localhost:8080/dist-http-example/2",
         MediaType.APPLICATION_XML_TYPE);
      }
   }

8.4 Using SSL and HTTP Basic Authentication with Oracle Coherence REST

The use of HTTP basic authentication does not preclude the use of SSL authentication. That is, both HTTP basic authentication and SSL can be used together for added protection. For details about setting up both SSL and HTTP basic authentication, see "Using HTTP Basic Authentication with Oracle Coherence REST" and "Using SSL Authentication With Oracle Coherence REST", respectively.

To specify the use of both HTTP basic authentication and SSL, add an <auth-method> element, within the http-acceptor element, that is set to cert+basic.

<proxy-scheme>
   <service-name>RestHttpProxyService</service-name>
   <acceptor-config>
      <http-acceptor>
         ...
         <socket-provider>
            <ssl>
            ...
            </ssl>
         </socket-provider>
         ...
         <auth-method>cert+basic</auth-method>
      </http-acceptor>
   </acceptor-config>
   <autostart>true</autostart>
</proxy-scheme>

8.5 Implementing Authorization For Oracle Coherence REST

Oracle Coherence REST relies on the Oracle Coherence*Extend authorization framework to restrict which operations a REST client performs on a cluster. For detailed instructions on implementing Oracle Coherence*Extend-style authorization, see "Implementing Extend Client Authorization".

Oracle Coherence*Extend-style authorization with REST requires basic HTTP authentication or HTTP basic authentication together with SSL authentication. That is, when implementing authorization, both HTTP basic authentication and SSL can be used together for added protection. For details on using HTTP basic authentication, see "Using HTTP Basic Authentication with Oracle Coherence REST". For details on using SSL with HTTP Basic Authentication, see "Using SSL and HTTP Basic Authentication with Oracle Coherence REST".

Note:

When using SSL and HTTP basic authentication together, make sure that SSL is setup as shown in "Using SSL Authentication With Oracle Coherence REST" in addition to setting up HTTP basic authentication.