4 Authorizing Access to Server-Side Operations
This chapter includes the following sections:
- Overview of Access Control Authorization
Access control authorization allows applications to define their own authorization logic to limit access to cluster operations. Authorization is based on identities that are represented as aPrincipal
within aSubject
. - Creating Access Control Authorization Implementations
Access control authorization requires an authorizer implementation that contains user-defined authorization logic. - Declaring Access Control Authorization Implementations
Access control authorization implementations must be declared so that the class is loaded when a cluster starts. - Enabling Access Control Authorization on a Partitioned Cache
A partition cache service must be configured to use an access control authorization implementation.
Overview of Access Control Authorization
Principal
within a Subject
.Applications are responsible for ensuring that the Subject
is present for caller threads. If the Subject
is missing or cannot be retrieved, then the operation fails with a SecurityException
error.
Applications implement the StorageAccessAuthorizer
interface to provide authorization logic. The implementations are declared in the operational override configuration file and must also be enabled on a partitioned cache by configuring the backing map of a distributed scheme in a cache configuration file. Access control authorization is only available for partitioned caches.
The StorageAccessAuthorizer
interface provides methods that are used to perform read, write, read any, and write any authorization checks. Coherence assumes that there is a logical consistency between authorization decisions made by StorageAccessAuthorizer
implementations. That is, for a given Subject
, the write authorization implies the read authorization for a given entry; the read any authorization implies read authorization for all entries; and, the write any authorization implies write and read authorization for all entries.
Table 4-1 lists which authorization checks are caused by NamedCache
API and BinaryEntry
API methods.
Table 4-1 Authorization Checks for Common Methods
Authorization Check | NamedCache API Methods | BinaryEntry API Methods |
---|---|---|
None |
|
|
Read |
|
|
Write |
|
|
Read Any |
|
|
Write Any |
|
Footnote 1
If a listener is a MapTriggerListener
, then a Write Any authorization check is performed instead.
Parent topic: Authorizing Access to Server-Side Operations
Creating Access Control Authorization Implementations
com.tangosol.net.security.StorageAccessAuthorizer
interface. The implementation should define which callers (based on the Subject
) are authorized to access entries and backing map contexts (BinaryEntry
and BackingMapManagerContext
, respectively).
Note:
The BinaryEntry
and BackingMapManagerContext
API provide the ability to retrieve the cache name, the service name, and full access to the service and cluster registries.
Example 4-1 Provides a sample StorageAccessAuthorizer
implementation that emits a log message for each authorization request. It is based on the AuditingAuthorizer
class that is provided with Coherence and used by the default access controller implementation.
Example 4-1 Sample StorageAccessAuthorizer Implementation
package com.examples.security; import com.tangosol.net.BackingMapContext; import com.tangosol.net.CacheFactory; import com.tangosol.net.security.StorageAccessAuthorizer; import com.tangosol.util.BinaryEntry; import javax.security.auth.Subject; public class MyLogAuthorizer implements StorageAccessAuthorizer { public MyLogAuthorizer() { this(false); } public MyLogAuthorizer(boolean fStrict) { f_fStrict = fStrict; } @Override public void checkRead(BinaryEntry entry, Subject subject, int nReason) { logEntryRequest(entry, subject, false, nReason); if (subject == null && f_fStrict) { throw new SecurityException("subject is not provided"); } } @Override public void checkWrite(BinaryEntry entry, Subject subject, int nReason) { logEntryRequest(entry, subject, true, nReason); if (subject == null && f_fStrict) { throw new SecurityException("subject is not provided"); } } @Override public void checkReadAny(BackingMapContext context, Subject subject, int nReason) { logMapRequest(context, subject, false, nReason); if (subject == null && f_fStrict) { throw new SecurityException("subject is not provided"); } } @Override public void checkWriteAny(BackingMapContext context, Subject subject, int nReason) { logMapRequest(context, subject, true, nReason); if (subject == null && f_fStrict) { throw new SecurityException("subject is not provided"); } } protected void logEntryRequest(BinaryEntry entry, Subject subject, boolean fWrite, int nReason) { CacheFactory.log('"' + (fWrite ? "Write" : "Read") + "\" request for key=\"" + entry.getKey() + (subject == null ? "\" from unidentified user" : "\" on behalf of " + subject.getPrincipals()) + " caused by \"" + nReason + "\"" , CacheFactory.LOG_INFO); } protected void logMapRequest(BackingMapContext context, Subject subject, boolean fWrite, int nReason) { CacheFactory.log('"' + (fWrite ? "Write-any" : "Read-any") + "\" request for cache \"" + context.getCacheName() + '"' + (subject == null ? " from unidentified user" : " on behalf of " + subject.getPrincipals()) + " caused by \"" + nReason + "\"" , CacheFactory.LOG_INFO); } private final boolean f_fStrict; }
Parent topic: Authorizing Access to Server-Side Operations
Declaring Access Control Authorization Implementations
To declare access control authorizer implementations, edit the operational override file and include a <storage-authorizers>
element, within the <cluster-config>
element, and declare each authorization implementation using a <storage-authorizer>
element. See storage-authorizer in Developing Applications with Oracle Coherence. Each declaration must include a unique id
attribute that is used by a partitioned cache to select an implementation. For example:
<cluster-config> <storage-authorizers> <storage-authorizer id="LogAuthorizer"> <class-name>package.MyLogAuthorizer</class-name> </storage-authorizer> </storage-authorizers> </cluster-config>
As an alternative, the <storage-authorizer>
element supports the use of a <class-factory-name>
element to use a factory class that is responsible for creating instances and a <method-name>
element to specify the static factory method on the factory class that performs object instantiation. For example:
<cluster-config> <storage-authorizers> <storage-authorizer id="LogAuthorizer"> <class-factory-name>package.MyAuthorizerFactory</class-factory-name> <method-name>getAuthorizer</method-name> </storage-authorizer> </storage-authorizers> </cluster-config>
Any initialization parameters that are required for an implementation can be specified using the <init-params>
element. For example:
<cluster-config> <storage-authorizers> <storage-authorizer id="LogAuthorizer"> <class-name>package.MyLogAuthorizer</class-name> <init-params> <init-param> <param-name>f_fStrict</param-name> <param-value>true</param-value> </init-param> </init-params> </storage-authorizer> </storage-authorizers> </cluster-config>
Parent topic: Authorizing Access to Server-Side Operations
Enabling Access Control Authorization on a Partitioned Cache
To enable access control authorization on a partitioned cache, edit the cache configuration file and add a <storage-authorizer>
element, within the <backing-map-scheme>
element of a distributed scheme, whose value is the id
attribute value of an authorization implementation that is declared in the operational override file. For example:
<distributed-scheme> ... <backing-map-scheme> <storage-authorizer>LogAuthorizer</storage-authorizer> <local-scheme/> </backing-map-scheme> <autostart>true</autostart> </distributed-scheme>
Parent topic: Authorizing Access to Server-Side Operations