Chapter 1. Configuring user roles and permissions
Authorization is a security feature that requires users to have certain permissions before they can access caches or interact with Data Grid resources. You assign roles to users that provide different levels of permissions, from read-only access to full, super user privileges.
1.1. Security authorization
Data Grid authorization secures your deployment by restricting user access.
User applications or clients must belong to a role that is assigned with sufficient permissions before they can perform operations on Cache Managers or caches.
For example, you configure authorization on a specific cache instance so that invoking Cache.get()
requires an identity to be assigned a role with read permission while Cache.put()
requires a role with write permission.
In this scenario, if a user application or client with the io
role attempts to write an entry, Data Grid denies the request and throws a security exception. If a user application or client with the writer
role sends a write request, Data Grid validates authorization and issues a token for subsequent operations.
Identities
Identities are security Principals of type java.security.Principal
. Subjects, implemented with the javax.security.auth.Subject
class, represent a group of security Principals. In other words, a Subject represents a user and all groups to which it belongs.
Identities to roles
Data Grid uses role mappers so that security principals correspond to roles, which you assign one or more permissions.
The following image illustrates how security principals correspond to roles:
1.1.1. User roles and permissions
Data Grid includes a default set of roles that grant users with permissions to access data and interact with Data Grid resources.
ClusterRoleMapper
is the default mechanism that Data Grid uses to associate security principals to authorization roles.
ClusterRoleMapper
matches principal names to role names. A user named admin
gets admin
permissions automatically, a user named deployer
gets deployer
permissions, and so on.
Role | Permissions | Description |
---|---|---|
| ALL | Superuser with all permissions including control of the Cache Manager lifecycle. |
| ALL_READ, ALL_WRITE, LISTEN, EXEC, MONITOR, CREATE |
Can create and delete Data Grid resources in addition to |
| ALL_READ, ALL_WRITE, LISTEN, EXEC, MONITOR |
Has read and write access to Data Grid resources in addition to |
| ALL_READ, MONITOR |
Has read access to Data Grid resources in addition to |
| MONITOR |
Can view statistics via JMX and the |
1.1.2. Permissions
Authorization roles have different permissions with varying levels of access to Data Grid. Permissions let you restrict user access to both Cache Managers and caches.
1.1.2.1. Cache Manager permissions
Permission | Function | Description |
---|---|---|
CONFIGURATION |
| Defines new cache configurations. |
LISTEN |
| Registers listeners against a Cache Manager. |
LIFECYCLE |
| Stops the Cache Manager. |
CREATE |
| Create and remove container resources such as caches, counters, schemas, and scripts. |
MONITOR |
|
Allows access to JMX statistics and the |
ALL | - | Includes all Cache Manager permissions. |
1.1.2.2. Cache permissions
Permission | Function | Description |
---|---|---|
READ |
| Retrieves entries from a cache. |
WRITE |
| Writes, replaces, removes, evicts data in a cache. |
EXEC |
| Allows code execution against a cache. |
LISTEN |
| Registers listeners against a cache. |
BULK_READ |
| Executes bulk retrieve operations. |
BULK_WRITE |
| Executes bulk write operations. |
LIFECYCLE |
| Starts and stops a cache. |
ADMIN |
| Allows access to underlying components and internal structures. |
MONITOR |
|
Allows access to JMX statistics and the |
ALL | - | Includes all cache permissions. |
ALL_READ | - | Combines the READ and BULK_READ permissions. |
ALL_WRITE | - | Combines the WRITE and BULK_WRITE permissions. |
Additional resources
1.1.3. Role mappers
Data Grid includes a PrincipalRoleMapper
API that maps security Principals in a Subject to authorization roles that you can assign to users.
1.1.3.1. Cluster role mappers
ClusterRoleMapper
uses a persistent replicated cache to dynamically store principal-to-role mappings for the default roles and permissions.
By default uses the Principal name as the role name and implements org.infinispan.security.MutableRoleMapper
which exposes methods to change role mappings at runtime.
-
Java class:
org.infinispan.security.mappers.ClusterRoleMapper
-
Declarative configuration:
<cluster-role-mapper />
1.1.3.2. Identity role mappers
IdentityRoleMapper
uses the Principal name as the role name.
-
Java class:
org.infinispan.security.mappers.IdentityRoleMapper
-
Declarative configuration:
<identity-role-mapper />
1.1.3.3. CommonName role mappers
CommonNameRoleMapper
uses the Common Name (CN) as the role name if the Principal name is a Distinguished Name (DN).
For example this DN, cn=managers,ou=people,dc=example,dc=com
, maps to the managers
role.
-
Java class:
org.infinispan.security.mappers.CommonRoleMapper
-
Declarative configuration:
<common-name-role-mapper />
1.1.3.4. Custom role mappers
Custom role mappers are implementations of org.infinispan.security.PrincipalRoleMapper
.
-
Declarative configuration:
<custom-role-mapper class="my.custom.RoleMapper" />
Additional resources
1.2. Access control list (ACL) cache
Data Grid caches roles that you grant to users internally for optimal performance. Whenever you grant or deny roles to users, Data Grid flushes the ACL cache to ensure user permissions are applied correctly.
If necessary, you can disable the ACL cache or configure it with the cache-size
and cache-timeout
attributes.
XML
<infinispan> <cache-container name="acl-cache-configuration"> <security cache-size="1000" cache-timeout="300000"> <authorization/> </security> </cache-container> </infinispan>
JSON
{ "infinispan" : { "cache-container" : { "name" : "acl-cache-configuration", "security" : { "cache-size" : "1000", "cache-timeout" : "300000", "authorization" : {} } } } }
YAML
infinispan: cacheContainer: name: "acl-cache-configuration" security: cache-size: "1000" cache-timeout: "300000" authorization: ~
Additional resources
1.3. Customizing roles and permissions
You can customize authorization settings in your Data Grid configuration to use role mappers with different combinations of roles and permissions.
Procedure
- Declare a role mapper and a set of custom roles and permissions in the Cache Manager configuration.
- Configure authorization for caches to restrict access based on user roles.
Custom roles and permissions configuration
XML
<infinispan> <cache-container name="custom-authorization"> <security> <authorization> <!-- Declare a role mapper that associates a security principal to each role. --> <identity-role-mapper /> <!-- Specify user roles and corresponding permissions. --> <role name="admin" permissions="ALL" /> <role name="reader" permissions="READ" /> <role name="writer" permissions="WRITE" /> <role name="supervisor" permissions="READ WRITE EXEC"/> </authorization> </security> </cache-container> </infinispan>
JSON
{ "infinispan" : { "cache-container" : { "name" : "custom-authorization", "security" : { "authorization" : { "identity-role-mapper" : null, "roles" : { "reader" : { "role" : { "permissions" : "READ" } }, "admin" : { "role" : { "permissions" : "ALL" } }, "writer" : { "role" : { "permissions" : "WRITE" } }, "supervisor" : { "role" : { "permissions" : "READ WRITE EXEC" } } } } } } } }
YAML
infinispan: cacheContainer: name: "custom-authorization" security: authorization: identityRoleMapper: "null" roles: reader: role: permissions: - "READ" admin: role: permissions: - "ALL" writer: role: permissions: - "WRITE" supervisor: role: permissions: - "READ" - "WRITE" - "EXEC"
1.4. Configuring caches with security authorization
Use authorization in your cache configuration to restrict user access. Before they can read or write cache entries, or create and delete caches, users must have a role with a sufficient level of permission.
Prerequisites
Ensure the
authorization
element is included in thesecurity
section of thecache-container
configuration.Data Grid enables security authorization in the Cache Manager by default and provides a global set of roles and permissions for caches.
- If necessary, declare custom roles and permissions in the Cache Manager configuration.
Procedure
- Open your cache configuration for editing.
-
Add the
authorization
element to caches to restrict user access based on their roles and permissions. - Save the changes to your configuration.
Authorization configuration
The following configuration shows how to use implicit authorization configuration with default roles and permissions:
XML
<distributed-cache> <security> <!-- Inherit authorization settings from the cache-container. --> <authorization/> </security> </distributed-cache>
JSON
{ "distributed-cache": { "security": { "authorization": { "enabled": true } } } }
YAML
distributedCache: security: authorization: enabled: true
Custom roles and permissions
XML
<distributed-cache> <security> <authorization roles="admin supervisor"/> </security> </distributed-cache>
JSON
{ "distributed-cache": { "security": { "authorization": { "enabled": true, "roles": ["admin","supervisor"] } } } }
YAML
distributedCache: security: authorization: enabled: true roles: ["admin","supervisor"]
1.5. Disabling security authorization
In local development environments you can disable authorization so that users do not need roles and permissions. Disabling security authorization means that any user can access data and interact with Data Grid resources.
Procedure
- Open your Data Grid configuration for editing.
-
Remove any
authorization
elements from thesecurity
configuration for the Cache Manager. -
Remove any
authorization
configuration from your caches. - Save the changes to your configuration.
1.6. Programmatically configuring authorization
When using embedded caches, you can configure authorization with the GlobalSecurityConfigurationBuilder
and ConfigurationBuilder
classes.
Procedure
Construct a
GlobalConfigurationBuilder
that enables authorization, specifies a role mapper, and defines a set of roles and permissions.GlobalConfigurationBuilder global = new GlobalConfigurationBuilder(); global .security() .authorization().enable() 1 .principalRoleMapper(new IdentityRoleMapper()) 2 .role("admin") 3 .permission(AuthorizationPermission.ALL) .role("reader") .permission(AuthorizationPermission.READ) .role("writer") .permission(AuthorizationPermission.WRITE) .role("supervisor") .permission(AuthorizationPermission.READ) .permission(AuthorizationPermission.WRITE) .permission(AuthorizationPermission.EXEC);
Enable authorization in the
ConfigurationBuilder
for caches to restrict access based on user roles.ConfigurationBuilder config = new ConfigurationBuilder(); config .security() .authorization() .enable(); 1
- 1
- Implicitly adds all roles from the global configuration.
If you do not want to apply all roles to a cache, explicitly define the roles that are authorized for caches as follows:
ConfigurationBuilder config = new ConfigurationBuilder(); config .security() .authorization() .enable() .role("admin") 1 .role("supervisor") .role("reader");
- 1
- Defines authorized roles for the cache. In this example, users who have the
writer
role only are not authorized for the "secured" cache. Data Grid denies any access requests from those users.
1.7. Code execution with security authorization
When you configure security authorization for embedded caches and then construct a DefaultCacheManager
, it returns a SecureCache
that checks the security context before invoking any operations. A SecureCache
also ensures that applications cannot retrieve lower-level insecure objects such as DataContainer
. For this reason, you must execute code with an identity that has the required authorization.
In Java, executing code with a specific identity usually means wrapping the code to be executed within a PrivilegedAction
as follows:
import org.infinispan.security.Security; Security.doAs(subject, new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { cache.put("key", "value"); } });
With Java 8, you can simplify the preceding call as follows:
Security.doAs(mySubject, PrivilegedAction<String>() -> cache.put("key", "value"));
The preceding call uses the Security.doAs()
method instead of Subject.doAs()
. You can use either method with Data Grid, however Security.doAs()
provides better performance.
If you need the current Subject, use the following call to retrieve it from the Data Grid context or from the AccessControlContext:
Security.getSubject();