Chapter 5. Security realms
Security realms integrate Data Grid Server deployments with the network protocols and infrastructure in your environment that control access and verify user identities.
5.1. Creating security realms
Add security realms to Data Grid Server configuration to control access to deployments. You can add one or more security realm to your configuration.
When you add security realms to your configuration, Data Grid Server automatically enables the matching authentication mechanisms for the Hot Rod and REST endpoints.
Prerequisites
- Add socket bindings to your Data Grid Server configuration as required.
Create keystores, or have a PEM file, to configure the security realm with TLS/SSL encryption.
Data Grid Server can also generate keystores at startup.
-
Provision the resources or services that the security realm configuration relies on.
For example, if you add a token realm, you need to provision OAuth services.
This procedure demonstrates how to configure multiple property realms. Before you begin, you need to create properties files that add users and assign permissions with the Command Line Interface (CLI). Use the user create
commands as follows:
user create <username> -p <changeme> -g <role> \ --users-file=application-users.properties \ --groups-file=application-groups.properties user create <username> -p <changeme> -g <role> \ --users-file=management-users.properties \ --groups-file=management-groups.properties
Run user create --help
for examples and more information.
Adding credentials to a properties realm with the CLI creates the user only on the server instance to which you are connected. You must manually synchronize credentials in a properties realm to each node in the cluster.
Procedure
- Open your Data Grid Server configuration for editing.
-
Use the
security-realms
element in thesecurity
configuration to contain create multiple security realms. Add a security realm with the
security-realm
element and give it a unique name with thename
attribute.To follow the example, create one security realm named
application-realm
and another namedmanagement-realm
.-
Provide the TLS/SSL identify for Data Grid Server with the
server-identities
element and configure a keystore as required. Specify the type of security realm by adding one the following elements or fields:
-
properties-realm
-
ldap-realm
-
token-realm
-
truststore-realm
-
Specify properties for the type of security realm you are configuring as appropriate.
To follow the example, specify the
*.properties
files you created with the CLI using thepath
attribute on theuser-properties
andgroup-properties
elements or fields.-
If you add multiple different types of security realm to your configuration, include the
distributed-realm
element or field so that Data Grid Server uses the realms in combination with each other. -
Configure Data Grid Server endpoints to use the security realm with the with the
security-realm
attribute. - Save the changes to your configuration.
Multiple property realms
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="application-realm"> <properties-realm groups-attribute="Roles"> <user-properties path="application-users.properties"/> <group-properties path="application-groups.properties"/> </properties-realm> </security-realm> <security-realm name="management-realm"> <properties-realm groups-attribute="Roles"> <user-properties path="management-users.properties"/> <group-properties path="management-groups.properties"/> </properties-realm> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "management-realm", "properties-realm": { "groups-attribute": "Roles", "user-properties": { "digest-realm-name": "management-realm", "path": "management-users.properties" }, "group-properties": { "path": "management-groups.properties" } } }, { "name": "application-realm", "properties-realm": { "groups-attribute": "Roles", "user-properties": { "digest-realm-name": "application-realm", "path": "application-users.properties" }, "group-properties": { "path": "application-groups.properties" } } }] } } }
YAML
server: security: securityRealms: - name: "management-realm" propertiesRealm: groupsAttribute: "Roles" userProperties: digestRealmName: "management-realm" path: "management-users.properties" groupProperties: path: "management-groups.properties" - name: "application-realm" propertiesRealm: groupsAttribute: "Roles" userProperties: digestRealmName: "application-realm" path: "application-users.properties" groupProperties: path: "application-groups.properties"
5.2. Setting up Kerberos identities
Add Kerberos identities to a security realm in your Data Grid Server configuration to use keytab files that contain service principal names and encrypted keys, derived from Kerberos passwords.
Prerequisites
- Have Kerberos service account principals.
keytab files can contain both user and service account principals. However, Data Grid Server uses service account principals only which means it can provide identity to clients and allow clients to authenticate with Kerberos servers.
In most cases, you create unique principals for the Hot Rod and REST endpoints. For example, if you have a "datagrid" server in the "INFINISPAN.ORG" domain you should create the following service principals:
-
hotrod/datagrid@INFINISPAN.ORG
identifies the Hot Rod service. -
HTTP/datagrid@INFINISPAN.ORG
identifies the REST service.
Procedure
Create keytab files for the Hot Rod and REST services.
- Linux
ktutil ktutil: addent -password -p datagrid@INFINISPAN.ORG -k 1 -e aes256-cts Password for datagrid@INFINISPAN.ORG: [enter your password] ktutil: wkt http.keytab ktutil: quit
- Microsoft Windows
ktpass -princ HTTP/datagrid@INFINISPAN.ORG -pass * -mapuser INFINISPAN\USER_NAME ktab -k http.keytab -a HTTP/datagrid@INFINISPAN.ORG
-
Copy the keytab files to the
server/conf
directory of your Data Grid Server installation. - Open your Data Grid Server configuration for editing.
-
Add a
server-identities
definition to the Data Grid server security realm. - Specify the location of keytab files that provide service principals to Hot Rod and REST connectors.
- Name the Kerberos service principals.
- Save the changes to your configuration.
Kerberos identity configuration
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="kerberos-realm"> <server-identities> <!-- Specifies a keytab file that provides a Kerberos identity. --> <!-- Names the Kerberos service principal for the Hot Rod endpoint. --> <!-- The required="true" attribute specifies that the keytab file must be present when the server starts. --> <kerberos keytab-path="hotrod.keytab" principal="hotrod/datagrid@INFINISPAN.ORG" required="true"/> <!-- Specifies a keytab file and names the Kerberos service principal for the REST endpoint. --> <kerberos keytab-path="http.keytab" principal="HTTP/localhost@INFINISPAN.ORG" required="true"/> </server-identities> </security-realm> </security-realms> </security> <endpoints> <endpoint socket-binding="default" security-realm="kerberos-realm"> <hotrod-connector> <authentication> <sasl server-name="datagrid" server-principal="hotrod/datagrid@INFINISPAN.ORG"/> </authentication> </hotrod-connector> <rest-connector> <authentication server-principal="HTTP/localhost@INFINISPAN.ORG"/> </rest-connector> </endpoint> </endpoints> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "kerberos-realm", "server-identities": [{ "kerberos": { "principal": "hotrod/datagrid@INFINISPAN.ORG", "keytab-path": "hotrod.keytab", "required": true }, "kerberos": { "principal": "HTTP/localhost@INFINISPAN.ORG", "keytab-path": "http.keytab", "required": true } }] }] }, "endpoints": { "endpoint": { "socket-binding": "default", "security-realm": "kerberos-realm", "hotrod-connector": { "authentication": { "security-realm": "kerberos-realm", "sasl": { "server-name": "datagrid", "server-principal": "hotrod/datagrid@INFINISPAN.ORG" } } }, "rest-connector": { "authentication": { "server-principal": "HTTP/localhost@INFINISPAN.ORG" } } } } } }
YAML
server: security: securityRealms: - name: "kerberos-realm" serverIdentities: - kerberos: principal: "hotrod/datagrid@INFINISPAN.ORG" keytabPath: "hotrod.keytab" required: "true" - kerberos: principal: "HTTP/localhost@INFINISPAN.ORG" keytabPath: "http.keytab" required: "true" endpoints: endpoint: socketBinding: "default" securityRealm: "kerberos-realm" hotrodConnector: authentication: sasl: serverName: "datagrid" serverPrincipal: "hotrod/datagrid@INFINISPAN.ORG" restConnector: authentication: securityRealm: "kerberos-realm" serverPrincipal" : "HTTP/localhost@INFINISPAN.ORG"
5.3. Property realms
Property realms use property files to define users and groups.
-
users.properties
contains Data Grid user credentials. Passwords can be pre-digested with theDIGEST-MD5
andDIGEST
authentication mechanisms. -
groups.properties
associates users with roles and permissions.
users.properties
myuser=a_password user2=another_password
groups.properties
myuser=supervisor,reader,writer user2=supervisor
Property realm configuration
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="default"> <!-- groups-attribute configures the "groups.properties" file to contain security authorization roles. --> <properties-realm groups-attribute="Roles"> <user-properties path="users.properties" relative-to="infinispan.server.config.path" plain-text="true"/> <group-properties path="groups.properties" relative-to="infinispan.server.config.path"/> </properties-realm> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "default", "properties-realm": { "groups-attribute": "Roles", "user-properties": { "digest-realm-name": "default", "path": "users.properties", "relative-to": "infinispan.server.config.path", "plain-text": true }, "group-properties": { "path": "groups.properties", "relative-to": "infinispan.server.config.path" } } }] } } }
YAML
server: security: securityRealms: - name: "default" propertiesRealm: # groupsAttribute configures the "groups.properties" file # to contain security authorization roles. groupsAttribute: "Roles" userProperties: digestRealmName: "default" path: "users.properties" relative-to: 'infinispan.server.config.path' plainText: "true" groupProperties: path: "groups.properties" relative-to: 'infinispan.server.config.path'
5.3.1. Property realm file structure
User properties files are structured as follows:
users.properties structure
#$REALM_NAME=default$ #$ALGORITHM=encrypted$ #Wed Jul 31 08:32:08 CEST 2024 admin=algorithm-1\:hash-1;algorithm-2\:hash-2;...
The first three lines are special comments that define the name of the realm ($REALM_NAME
), whether the passwords are stored in clear
or encrypted
format ($ALGORITHM
) and the timestamp of the last update.
User credentials are stored in traditional key/value format: the key corresponds to the username and the value corresponds to the password. Encrypted passwords are represented as semi-colon-separated algorithm/hash pairs, with the hash encoded in Base64.
Credentials are encrypted using the realm name. Changing a realm’s name requires re-encrypting all the passwords. Use the Data Grid CLI to enter the correct security realm name to the file.
5.4. LDAP realms
LDAP realms connect to LDAP servers, such as OpenLDAP, Red Hat Directory Server, Apache Directory Server, or Microsoft Active Directory, to authenticate users and obtain membership information.
LDAP servers can have different entry layouts, depending on the type of server and deployment. It is beyond the scope of this document to provide examples for all possible configurations.
5.4.1. LDAP connection properties
Specify the LDAP connection properties in the LDAP realm configuration.
The following properties are required:
url |
Specifies the URL of the LDAP server. The URL should be in format |
principal | Specifies a distinguished name (DN) of a valid user in the LDAp server. The DN uniquely identifies the user within the LDAP directory structure. |
credential | Corresponds to the password associated with the principal mentioned above. |
The principal for LDAP connections must have necessary privileges to perform LDAP queries and access specific attributes.
Enabling connection-pooling
significantly improves the performance of authentication to LDAP servers. The connection pooling mechanism is provided by the JDK. For more information see Connection Pooling Configuration and Java Tutorials: Pooling.
5.4.2. LDAP realm user authentication methods
Configure the user authentication method in the LDAP realm.
The LDAP realm can authenticate users in two ways:
Hashed password comparison |
by comparing the hashed password stored in a user’s password attribute (usually |
Direct verification | by authenticating against the LDAP server using the supplied credentials
Direct verification is the only approach that works with Active Directory, because access to the |
You cannot use endpoint authentication mechanisms that performs hashing with the direct-verification
attribute, since this method requires having the password in clear text. As a result you must use the BASIC
authentication mechanism with the REST endpoint and PLAIN
with the Hot Rod endpoint to integrate with Active Directory Server. A more secure alternative is to use Kerberos, which allows the SPNEGO
, GSSAPI
, and GS2-KRB5
authentication mechanisms.
The LDAP realm searches the directory to find the entry which corresponds to the authenticated user. The rdn-identifier
attribute specifies an LDAP attribute that finds the user entry based on a provided identifier, which is typically a username; for example, the uid
or sAMAccountName
attribute. Add search-recursive="true"
to the configuration to search the directory recursively. By default, the search for the user entry uses the (rdn_identifier={0})
filter. You can specify a different filter using the filter-name
attribute.
5.4.3. Mapping user entries to their associated groups
In the LDAP realm configuration, specify the attribute-mapping
element to retrieve and associate all groups that a user is a member of.
The membership information is stored typically in two ways:
-
Under group entries that usually have class
groupOfNames
orgroupOfUniqueNames
in themember
attribute. This is the default behavior in most LDAP installations, except for Active Directory. In this case, you can use an attribute filter. This filter searches for entries that match the supplied filter, which locates groups with amember
attribute equal to the user’s DN. The filter then extracts the group entry’s CN as specified byfrom
, and adds it to the user’sRoles
. In the user entry in the
memberOf
attribute. This is typically the case for Active Directory. In this case you should use an attribute reference such as the following:<attribute-reference reference="memberOf" from="cn" to="Roles" />
This reference gets all
memberOf
attributes from the user’s entry, extracts the CN as specified byfrom
, and adds them to the user’s groups (Roles
is the internal name used to map the groups).
5.4.4. LDAP realm configuration reference
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="ldap-realm"> <!-- Specifies connection properties. --> <ldap-realm url="ldap://my-ldap-server:10389" principal="uid=admin,ou=People,dc=infinispan,dc=org" credential="strongPassword" connection-timeout="3000" read-timeout="30000" connection-pooling="true" referral-mode="ignore" page-size="30" direct-verification="true"> <!-- Defines how principals are mapped to LDAP entries. --> <identity-mapping rdn-identifier="uid" search-dn="ou=People,dc=infinispan,dc=org" search-recursive="false"> <!-- Retrieves all the groups of which the user is a member. --> <attribute-mapping> <attribute from="cn" to="Roles" filter="(&(objectClass=groupOfNames)(member={1}))" filter-dn="ou=Roles,dc=infinispan,dc=org"/> </attribute-mapping> </identity-mapping> </ldap-realm> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "ldap-realm", "ldap-realm": { "url": "ldap://my-ldap-server:10389", "principal": "uid=admin,ou=People,dc=infinispan,dc=org", "credential": "strongPassword", "connection-timeout": "3000", "read-timeout": "30000", "connection-pooling": "true", "referral-mode": "ignore", "page-size": "30", "direct-verification": "true", "identity-mapping": { "rdn-identifier": "uid", "search-dn": "ou=People,dc=infinispan,dc=org", "search-recursive": "false", "attribute-mapping": [{ "from": "cn", "to": "Roles", "filter": "(&(objectClass=groupOfNames)(member={1}))", "filter-dn": "ou=Roles,dc=infinispan,dc=org" }] } } }] } } }
YAML
server: security: securityRealms: - name: ldap-realm ldapRealm: url: 'ldap://my-ldap-server:10389' principal: 'uid=admin,ou=People,dc=infinispan,dc=org' credential: strongPassword connectionTimeout: '3000' readTimeout: '30000' connectionPooling: true referralMode: ignore pageSize: '30' directVerification: true identityMapping: rdnIdentifier: uid searchDn: 'ou=People,dc=infinispan,dc=org' searchRecursive: false attributeMapping: - filter: '(&(objectClass=groupOfNames)(member={1}))' filterDn: 'ou=Roles,dc=infinispan,dc=org' from: cn to: Roles
5.4.4.1. LDAP realm principal rewriting
Principals obtained by SASL authentication mechanisms such as GSSAPI
, GS2-KRB5
and Negotiate
usually include the domain name, for example myuser@INFINISPAN.ORG
. Before using these principals in LDAP queries, it is necessary to transform them to ensure their compatibility. This process is called rewriting.
Data Grid includes the following transformers:
case-principal-transformer |
rewrites the principal to either all uppercase or all lowercase. For example |
common-name-principal-transformer |
rewrites principals in the LDAP Distinguished Name format (as defined by RFC 4514). It extracts the first attribute of type |
regex-principal-transformer | rewrites principals using a regular expression with capturing groups, allowing, for example, for extractions of any substring. |
5.4.4.2. LDAP principal rewriting configuration reference
Case principal transformer
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="ldap-realm"> <ldap-realm url="ldap://${org.infinispan.test.host.address}:10389" principal="uid=admin,ou=People,dc=infinispan,dc=org" credential="strongPassword"> <name-rewriter> <!-- Defines a rewriter that transforms usernames to lowercase --> <case-principal-transformer uppercase="false"/> </name-rewriter> <!-- further configuration omitted --> </ldap-realm> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "ldap-realm", "ldap-realm": { "principal": "uid=admin,ou=People,dc=infinispan,dc=org", "url": "ldap://${org.infinispan.test.host.address}:10389", "credential": "strongPassword", "name-rewriter": { "case-principal-transformer": { "uppercase": false } } } }] } } }
YAML
server: security: securityRealms: - name: "ldap-realm" ldapRealm: principal: "uid=admin,ou=People,dc=infinispan,dc=org" url: "ldap://${org.infinispan.test.host.address}:10389" credential: "strongPassword" nameRewriter: casePrincipalTransformer: uppercase: false # further configuration omitted
Common name principal transformer
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="ldap-realm"> <ldap-realm url="ldap://${org.infinispan.test.host.address}:10389" principal="uid=admin,ou=People,dc=infinispan,dc=org" credential="strongPassword"> <name-rewriter> <!-- Defines a rewriter that obtains the first CN from a DN --> <common-name-principal-transformer /> </name-rewriter> <!-- further configuration omitted --> </ldap-realm> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "ldap-realm", "ldap-realm": { "principal": "uid=admin,ou=People,dc=infinispan,dc=org", "url": "ldap://${org.infinispan.test.host.address}:10389", "credential": "strongPassword", "name-rewriter": { "common-name-principal-transformer": {} } } }] } } }
YAML
server: security: securityRealms: - name: "ldap-realm" ldapRealm: principal: "uid=admin,ou=People,dc=infinispan,dc=org" url: "ldap://${org.infinispan.test.host.address}:10389" credential: "strongPassword" nameRewriter: commonNamePrincipalTransformer: ~ # further configuration omitted
Regex principal transformer
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="ldap-realm"> <ldap-realm url="ldap://${org.infinispan.test.host.address}:10389" principal="uid=admin,ou=People,dc=infinispan,dc=org" credential="strongPassword"> <name-rewriter> <!-- Defines a rewriter that extracts the username from the principal using a regular expression. --> <regex-principal-transformer pattern="(.*)@INFINISPAN\.ORG" replacement="$1"/> </name-rewriter> <!-- further configuration omitted --> </ldap-realm> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "ldap-realm", "ldap-realm": { "principal": "uid=admin,ou=People,dc=infinispan,dc=org", "url": "ldap://${org.infinispan.test.host.address}:10389", "credential": "strongPassword", "name-rewriter": { "regex-principal-transformer": { "pattern": "(.*)@INFINISPAN\\.ORG", "replacement": "$1" } } } }] } } }
YAML
server: security: securityRealms: - name: "ldap-realm" ldapRealm: principal: "uid=admin,ou=People,dc=infinispan,dc=org" url: "ldap://${org.infinispan.test.host.address}:10389" credential: "strongPassword" nameRewriter: regexPrincipalTransformer: pattern: (.*)@INFINISPAN\.ORG replacement: "$1" # further configuration omitted
5.4.4.3. LDAP user and group mapping process with Data Grid
This example illustrates the process of loading and internally mapping LDAP users and groups to Data Grid subjects. The following is a LDIF (LDAP Data Interchange Format) file, which describes multiple LDAP entries:
LDIF
# Users dn: uid=root,ou=People,dc=infinispan,dc=org objectclass: top objectclass: uidObject objectclass: person uid: root cn: root sn: root userPassword: strongPassword # Groups dn: cn=admin,ou=Roles,dc=infinispan,dc=org objectClass: top objectClass: groupOfNames cn: admin description: the Infinispan admin group member: uid=root,ou=People,dc=infinispan,dc=org dn: cn=monitor,ou=Roles,dc=infinispan,dc=org objectClass: top objectClass: groupOfNames cn: monitor description: the Infinispan monitor group member: uid=root,ou=People,dc=infinispan,dc=org
The root
user is a member of the admin
and monitor
groups.
When a request to authenticate the user root
with the password strongPassword
is made on one of the endpoints, the following operations are performed:
- The username is optionally rewritten using the chosen principal transformer.
-
The realm searches within the
ou=People,dc=infinispan,dc=org
tree for an entry whoseuid
attribute is equal toroot
and finds the entry with DNuid=root,ou=People,dc=infinispan,dc=org
, which becomes the user principal. -
The realm searches within the
u=Roles,dc=infinispan,dc=org
tree for entries ofobjectClass=groupOfNames
that includeuid=root,ou=People,dc=infinispan,dc=org
in themember
attribute. In this case it finds two entries:cn=admin,ou=Roles,dc=infinispan,dc=org
andcn=monitor,ou=Roles,dc=infinispan,dc=org
. From these entries, it extracts thecn
attributes which become the group principals.
The resulting subject will therefore look like:
-
NamePrincipal:
uid=root,ou=People,dc=infinispan,dc=org
-
RolePrincipal:
admin
-
RolePrincipal:
monitor
At this point, the global authorization mappers are applied on the above subject to convert the principals into roles. The roles are then expanded into a set of permissions, which are validated against the requested cache and operation.
5.5. Token realms
Token realms use external services to validate tokens and require providers that are compatible with RFC-7662 (OAuth2 Token Introspection), such as Red Hat SSO.
Token realm configuration
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="token-realm"> <!-- Specifies the URL of the authentication server. --> <token-realm name="token" auth-server-url="https://oauth-server/auth/"> <!-- Specifies the URL of the token introspection endpoint. --> <oauth2-introspection introspection-url="https://oauth-server/auth/realms/infinispan/protocol/openid-connect/token/introspect" client-id="infinispan-server" client-secret="1fdca4ec-c416-47e0-867a-3d471af7050f"/> </token-realm> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "token-realm", "token-realm": { "auth-server-url": "https://oauth-server/auth/", "oauth2-introspection": { "client-id": "infinispan-server", "client-secret": "1fdca4ec-c416-47e0-867a-3d471af7050f", "introspection-url": "https://oauth-server/auth/realms/infinispan/protocol/openid-connect/token/introspect" } } }] } } }
YAML
server: security: securityRealms: - name: token-realm tokenRealm: authServerUrl: 'https://oauth-server/auth/' oauth2Introspection: clientId: infinispan-server clientSecret: '1fdca4ec-c416-47e0-867a-3d471af7050f' introspectionUrl: 'https://oauth-server/auth/realms/infinispan/protocol/openid-connect/token/introspect'
5.6. Trust store realms
Trust store realms use certificates, or certificates chains, that verify Data Grid Server and client identities when they negotiate connections.
- Keystores
- Contain server certificates that provide a Data Grid Server identity to clients. If you configure a keystore with server certificates, Data Grid Server encrypts traffic using industry standard SSL/TLS protocols.
- Trust stores
- Contain client certificates, or certificate chains, that clients present to Data Grid Server. Client trust stores are optional and allow Data Grid Server to perform client certificate authentication.
Client certificate authentication
You must add the require-ssl-client-auth="true"
attribute to the endpoint configuration if you want Data Grid Server to validate or authenticate client certificates.
Trust store realm configuration
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="trust-store-realm"> <server-identities> <ssl> <!-- Provides an SSL/TLS identity with a keystore that contains server certificates. --> <keystore path="server.p12" relative-to="infinispan.server.config.path" keystore-password="secret" alias="server"/> <!-- Configures a trust store that contains client certificates or part of a certificate chain. --> <truststore path="trust.p12" relative-to="infinispan.server.config.path" password="secret"/> </ssl> </server-identities> <!-- Authenticates client certificates against the trust store. If you configure this, the trust store must contain the public certificates for all clients. --> <truststore-realm/> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "trust-store-realm", "server-identities": { "ssl": { "keystore": { "path": "server.p12", "relative-to": "infinispan.server.config.path", "keystore-password": "secret", "alias": "server" }, "truststore": { "path": "trust.p12", "relative-to": "infinispan.server.config.path", "password": "secret" } } }, "truststore-realm": {} }] } } }
YAML
server: security: securityRealms: - name: "trust-store-realm" serverIdentities: ssl: keystore: path: "server.p12" relative-to: "infinispan.server.config.path" keystore-password: "secret" alias: "server" truststore: path: "trust.p12" relative-to: "infinispan.server.config.path" password: "secret" truststoreRealm: ~
5.7. Distributed security realms
Distributed realms combine multiple different types of security realms. When users attempt to access the Hot Rod or REST endpoints, Data Grid Server uses each security realm in turn until it finds one that can perform the authentication.
Distributed realm configuration
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="distributed-realm"> <ldap-realm url="ldap://my-ldap-server:10389" principal="uid=admin,ou=People,dc=infinispan,dc=org" credential="strongPassword"> <identity-mapping rdn-identifier="uid" search-dn="ou=People,dc=infinispan,dc=org" search-recursive="false"> <attribute-mapping> <attribute from="cn" to="Roles" filter="(&(objectClass=groupOfNames)(member={1}))" filter-dn="ou=Roles,dc=infinispan,dc=org"/> </attribute-mapping> </identity-mapping> </ldap-realm> <properties-realm groups-attribute="Roles"> <user-properties path="users.properties" relative-to="infinispan.server.config.path"/> <group-properties path="groups.properties" relative-to="infinispan.server.config.path"/> </properties-realm> <distributed-realm/> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "distributed-realm", "ldap-realm": { "principal": "uid=admin,ou=People,dc=infinispan,dc=org", "url": "ldap://my-ldap-server:10389", "credential": "strongPassword", "identity-mapping": { "rdn-identifier": "uid", "search-dn": "ou=People,dc=infinispan,dc=org", "search-recursive": false, "attribute-mapping": { "attribute": { "filter": "(&(objectClass=groupOfNames)(member={1}))", "filter-dn": "ou=Roles,dc=infinispan,dc=org", "from": "cn", "to": "Roles" } } } }, "properties-realm": { "groups-attribute": "Roles", "user-properties": { "digest-realm-name": "distributed-realm", "path": "users.properties" }, "group-properties": { "path": "groups.properties" } }, "distributed-realm": {} }] } } }
YAML
server: security: securityRealms: - name: "distributed-realm" ldapRealm: principal: "uid=admin,ou=People,dc=infinispan,dc=org" url: "ldap://my-ldap-server:10389" credential: "strongPassword" identityMapping: rdnIdentifier: "uid" searchDn: "ou=People,dc=infinispan,dc=org" searchRecursive: "false" attributeMapping: attribute: filter: "(&(objectClass=groupOfNames)(member={1}))" filterDn: "ou=Roles,dc=infinispan,dc=org" from: "cn" to: "Roles" propertiesRealm: groupsAttribute: "Roles" userProperties: digestRealmName: "distributed-realm" path: "users.properties" groupProperties: path: "groups.properties" distributedRealm: ~
5.8. Aggregate security realms
Aggregate realms combine multiple realms: the first one for the authentication steps and the others for loading the identity for the authorization steps. For example, this can be used to authenticate users via a client certificate, and retrieve identity from a properties or LDAP realm.
Aggregate realm configuration
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="default" default-realm="aggregate"> <server-identities> <ssl> <keystore path="server.pfx" password="secret" alias="server"/> <truststore path="trust.pfx" password="secret"/> </ssl> </server-identities> <properties-realm name="properties" groups-attribute="Roles"> <user-properties path="users.properties" relative-to="infinispan.server.config.path"/> <group-properties path="groups.properties" relative-to="infinispan.server.config.path"/> </properties-realm> <truststore-realm name="trust"/> <aggregate-realm authentication-realm="trust" authorization-realms="properties"> <name-rewriter> <common-name-principal-transformer/> </name-rewriter> </aggregate-realm> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [ { "name": "aggregate-realm", "default-realm": "aggregate", "server-identities": { "ssl": { "keystore": { "path": "server.p12", "relative-to": "infinispan.server.config.path", "keystore-password": "secret", "alias": "server" }, "truststore": { "path": "trust.p12", "relative-to": "infinispan.server.config.path", "password": "secret" } } }, "properties-realm": { "name": "properties", "groups-attribute": "Roles", "user-properties": { "digest-realm-name": "distributed-realm", "path": "users.properties" }, "group-properties": { "path": "groups.properties" } }, "truststore-realm": { "name": "trust" }, "aggregate-realm": { "authentication-realm": "trust", "authorization-realms": ["properties"], "name-rewriter": { "common-name-principal-transformer": {} } } } ] } } }
YAML
server: security: securityRealms: - name: "aggregate-realm" defaultRealm: "aggregate" serverIdentities: ssl: keystore: path: "server.p12" relative-to: "infinispan.server.config.path" keystore-password: "secret" alias: "server" truststore: path: "trust.p12" relative-to: "infinispan.server.config.path" password: "secret" truststoreRealm: name: "trust" propertiesRealm: name: "properties" groupsAttribute: "Roles" userProperties: digestRealmName: "distributed-realm" path: "users.properties" groupProperties: path: "groups.properties" aggregateRealm: authenticationRealm: "trust" authorizationRealms: - "properties" nameRewriter: common-name-principal-transformer: ~
5.8.1. Name rewriters
Principal names may have different forms, depending on the security realm type:
- Properties and Token realms may return simple strings
- Trust and LDAP realms may return X.500-style distinguished names
-
Kerberos realms may return
user@domain
-style names
Names must be normalized to a common form when using the aggregate realm using one of the following transformers.
5.8.1.1. Case Principal Transformer
The case-principal-transformer
transforms a name to all uppercase or all lowercase letters.
XML
<aggregate-realm authentication-realm="trust" authorization-realms="properties"> <name-rewriter> <case-principal-transformer uppercase="false"/> </name-rewriter> </aggregate-realm>
JSON
{ "aggregate-realm": { "authentication-realm": "trust", "authorization-realms": [ "properties" ], "name-rewriter": { "case-principal-transformer": { "uppercase": "false" } } } }
YAML
aggregateRealm: authenticationRealm: "trust" authorizationRealms: - "properties" nameRewriter: casePrincipalTransformer: uppercase: false
5.8.1.2. Common Name Principal Transformer
The common-name-principal-transformer
extracts the first CN
element from a DN
used by LDAP or Certificates. For example, given a principal in the form CN=app1,CN=serviceA,OU=applications,DC=infinispan,DC=org
, the following configuration will extract app1
as the principal.
XML
<aggregate-realm authentication-realm="trust" authorization-realms="properties"> <name-rewriter> <common-name-principal-transformer/> </name-rewriter> </aggregate-realm>
JSON
{ "aggregate-realm": { "authentication-realm": "trust", "authorization-realms": [ "properties" ], "name-rewriter": { "common-name-principal-transformer": {} } } }
YAML
aggregateRealm: authenticationRealm: "trust" authorizationRealms: - "properties" nameRewriter: commonNamePrincipalTransformer: ~
5.8.1.3. Regex Principal Transformer
The regex-principal-transformer
can perform find and replace using a regular expression. The example shows how to extract the local-part from a user@domain.com
identifier.
XML
<aggregate-realm authentication-realm="trust" authorization-realms="properties"> <name-rewriter> <regex-principal-transformer pattern="([^@]+)@.*" replacement="$1" replace-all="false"/> </name-rewriter> </aggregate-realm>
JSON
{ "aggregate-realm": { "authentication-realm": "trust", "authorization-realms": [ "properties" ], "name-rewriter": { "regex-principal-transformer": { "pattern" : "([^@]+)@.*", "replacement": "$1", "replace-all": false } } } }
YAML
aggregateRealm: authenticationRealm: "trust" authorizationRealms: - "properties" nameRewriter: regexPrincipalTransformer: pattern: "([^@]+)@.*" replacement: "$1" replaceAll: false
5.9. Security realm caching
Security realms implement caching to avoid having to repeatedly retrieve data which usually changes very infrequently. By default
Realm caching realm configuration
XML
<server xmlns="urn:infinispan:server:15.0"> <security> <security-realms> <security-realm name="default" cache-max-size="1024" cache-lifespan="120000"> </security-realm> </security-realms> </security> </server>
JSON
{ "server": { "security": { "security-realms": [{ "name": "default", "cache-max-size": 1024, "cache-lifespan": 120000 }] } } }
YAML
server: security: securityRealms: - name: "default" cache-max-size: 1024 cache-lifespan: 120000
5.9.1. Flushing realm caches
Use the CLI to flush security realm caches across the whole cluster.
[node-1@mycluster//containers/default]> server aclcache flush