8 Securing Oracle Coherence REST

Authentication and authorization can be used to secure Oracle Coherence REST. If you are new to Coherence REST, See Using Coherence REST in Developing Remote Clients for Oracle Coherence.

This chapter includes the following sections:

Overview of Securing Oracle Coherence REST

Oracle Coherence REST security uses both authentication and authorization to restrict access to cluster resources. Authentication and authorization are disabled by default and are enabled as required. 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.

Using HTTP Basic Authentication with Oracle Coherence REST

You can configure an HTTP acceptor and login module to provide authentication for 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.

This section includes the following topics:

Specify Basic Authentication for an HTTP Acceptor

To specify basic authentication for an HTTP Acceptor:

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>

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. See LoginModule in Java Authentication and Authorization Service (JAAS) Reference Guide.

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.

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. See Generating Java SSL Artifacts.

Using SSL Authentication With Oracle Coherence REST

You can use SSL to provide authentication for Coherence REST. SSL provides an authentication mechanism that relies on digital certificates and encryption keys to establish both identity and trust. 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.

This section includes the following topics:

Specify Basic Authentication for an HTTP Acceptor

To specify basic authentication for an HTTP Acceptor:

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>

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 socket-provider in Developing Applications with Oracle Coherence.

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 socket-providers in Developing Applications with Oracle Coherence.

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>

Access Secured REST Services

The following example demonstrates a Jersey-based client that accesses REST services that require certificate and HTTP basic authentication.

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);
      }
   }

Using SSL and HTTP Basic Authentication with Oracle Coherence REST

You can use SSL together with HTTP basic authentication for added protection when securing Coherence REST. 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>

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.