Skip to content

Instantly share code, notes, and snippets.

@tristantarrant
Created October 9, 2019 07:46
Show Gist options
  • Select an option

  • Save tristantarrant/023350670e8519c8c70014022208a9aa to your computer and use it in GitHub Desktop.

Select an option

Save tristantarrant/023350670e8519c8c70014022208a9aa to your computer and use it in GitHub Desktop.
Hot Rod authentication GSSAPI/Kerberos

GSSAPI/Kerberos Authentication for Hot Rod

krb5.conf

Prepare a krb5.conf file which describes your Kerberos environment (domain, KDC, etc.)

krb5.conf
[libdefaults]
default_realm = INFINISPAN.ORG
default_tgs_enctypes = aes128-cts-hmac-sha1-96
default_tkt_enctypes = aes128-cts-hmac-sha1-96
kdc_timeout = 5000
dns_lookup_realm = false
dns_fallback = false
dns_lookup_kdc = false
allow_weak_crypto = yes
forwardable = true
rnds = false

[realms]
INFINISPAN.ORG = {
kdc = localhost:60088
default_domain = infinispan.org
}

[login]
krb4_convert = true
krb4_get_tickets = false

[domain_realm]
.infinispan.org = INFINISPAN.ORG
infinispan.org = INFINISPAN.ORG
localhost = INFINISPAN.ORG
localhost.localdomain = INFINISPAN.ORG

Add the following system-properties to the server configuration to point to the krb5.conf file.

standalone.xml
<system-properties>
    <property name="java.security.krb5.conf" value="${jboss.server.config.dir}/krb5.conf"/>
    <!-- Set this to true to trace Kerberos messages -->
    <property name="java.security.krb5.debug" value="false"/>
    <property name="jboss.security.disable.secdomain.option" value="true"/>
</system-properties>

Service Principal

  • Create a service principal in your KDC that will identify your Hot Rod connector. The principal should be named hotrod/instance@REALM. Our example uses datagrid for the instance name and INFINISPAN.ORG for the realm.

  • Export the service principal to a keytab file:

    • ktutil (linux/unix)

    • ktab (windows)

  • Put the keytab in the server configuration directory (e.g. standalone/configuration/)

  • Add a security domain pointing to the keytab:

standalone.xml
<subsystem xmlns="urn:jboss:domain:security:2.0">
   <security-domains>
   ...
      <security-domain name="hotrod-domain" cache-type="default">
         <authentication>
            <login-module code="Kerberos" flag="required">
               <module-option name="storeKey" value="true"/>
               <module-option name="useKeyTab" value="true"/>
               <module-option name="refreshKrb5Config" value="true"/>
               <module-option name="principal" value="hotrod/[email protected]"/>
               <module-option name="keyTab" value="${jboss.server.config.dir}/hotrod_service.keytab"/>
               <module-option name="doNotPrompt" value="true"/>
            </login-module>
         </authentication>
      </security-domain>
      ...
   </security-domains>
</subsystem>

Hot Rod connector authentication

  • Add the GSSAPI SASL configuration to the Hot Rod endpoint. Make sure the server-name attribute is equal to the instance name in the service principal. The server-context-name attribute points to the security domain we defined above.

standalone.xml
<subsystem xmlns="urn:infinispan:server:endpoint:9.4">
    <hotrod-connector socket-binding="hotrod" cache-container="local">
        <authentication security-realm="ApplicationRealm">
            <sasl server-context-name="hotrod-domain" server-name="datagrid" mechanisms="GSSAPI" qop="auth" strength="high medium low">
               <policy>
                  <no-anonymous value="true"/>
               </policy>
            </sasl>
        </authentication>
    </hotrod-connector>
</subsystem>
Note
when using the GSSAPI mechanism, the security-realm set on the authentication element will only be used to enrich the user with authorization information (e.g. groups). It will NOT be used for authentication.

Adding LDAP-based authorization

Add an LDAP connection

Create an outbound connection to your LDAP server. The search-dn and search-credentials attributes indicate the credentials to be used to perform searches on the LDAP server.

standalone.xml
<outbound-connections>
    <ldap name="ldap_connection" url="ldap://localhost:10389" search-dn="uid=admin,ou=People,dc=infinispan,dc=org" search-credential="strongPassword"/>
</outbound-connections>

Add an LDAP realm

Configure an LDAP realm. This has two parts:

  • a search which maps usernames to LDAP DNs (Distinguished Names)

  • a search which retrieves all groups a user belongs to

These are specific to the way your LDAP directory is laid out.

standalone.xml
<security-realm name="LdapRealm">
    <authentication>
         <!-- Will not be used -->
        <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
    </authentication>
    <authorization>
        <ldap connection="ldap_connection">
            <username-to-dn force="false">
                <username-filter recursive="true" base-dn="ou=People,dc=infinispan,dc=org" attribute="uid" user-dn-attribute="dn"/>
            </username-to-dn>
            <group-search group-dn-attribute="dn" group-name-attribute="cn">
                <group-to-principal recursive="true" base-dn="ou=Roles,dc=infinispan,dc=org" search-by="DISTINGUISHED_NAME">
                    <membership-filter principal-attribute="member"/>
                </group-to-principal>
            </group-search>
        </ldap>
    </authorization>
</security-realm>

Ensure that the Hot Rod connector uses the new realm.

Cache container authorization

Add the authorization element to the cache-container. The role names MUST match the group names which will have been populated by the realm.

standalone.xml
<subsystem xmlns="urn:infinispan:server:core:9.4" default-cache-container="default">
   <cache-container name="default" default-cache="default" statistics="true">
     ...
     <security>
        <authorization>
           <identity-role-mapper/>
           <role name="Admin" permissions="ALL"/>
           <role name="Reader" permissions="READ"/>
           <role name="Writer" permissions="WRITE"/>
           <role name="Supervisor" permissions="READ WRITE EXEC BULK_READ"/>
        </authorization>
     </security>
     ..
   </cache-container>
</subsystem>

Cache authorization

Define a cache

standalone.xml
<subsystem xmlns="urn:infinispan:server:core:9.4" default-cache-container="default">
   <cache-container name="default" default-cache="default" statistics="true">
      ...
      <distributed-cache name="default">
         <security>
            <authorization roles="Admin Reader Writer Supervisor" enabled="true"/>
         </security>
      </distributed-cache>
      ...
   </cache-container>
</subsystem>

Configuring the client

The client can be configured to authenticate using two methods: through credentials supplied via a callback handler or via a keytab.

Callback

Create a JAAS hotrod.login.conf file:

hotrod.login.conf
HotRodKrbClient {
    com.sun.security.auth.module.Krb5LoginModule required
    refreshKrb5Config=true
    storeKey=true
    client=TRUE;
};

Point the JDK security to your hotrod.login.conf and krb5.conf file using the appropriate system properties, either on the command-line:

java -Djava.security.krb5.conf=/path/to/krb5.conf -Djava.security.auth.login.config=/path/to/hotrod.login.conf ...

or programmatically:

System.setProperty("java.security.krb5.conf", "/path/to/krb5.conf");
System.setProperty("java.security.auth.login.config", "/path/to/hotrod.login.conf");
Note
if using programmatic configuration and you have a security manager installed, make sure your code is allowed to change system properties.
Client.java
// Obtain a subject by logging to the KDC using username and password
LoginContext lc = new LoginContext("HotRodKrbClient", new BasicCallbackHandler("client", "INFINISPAN.ORG", "password".toCharArray()));
lc.login();
Subject subject = lc.getSubject();
// Configure the client for GSSAPI
ConfigurationBuilder config = new ConfigurationBuilder();
config
    .addServer().host("host.address").port(11222)
    .security().authentication().enable()
    .saslMechanism("GSSAPI")
    .clientSubject(subject)
    .serverName("datagrid");
RemoteCacheManager rcm = new RemoteCacheManager(config.build());

Keytab

Create a JAAS login.conf file pointing to the keytab:

hotrod-keytab.login.conf
HotRodKrbClientWithKeyTab {
    com.sun.security.auth.module.Krb5LoginModule required
    refreshKrb5Config=true
    useTicketCache=false
    doNotPrompt=true
    client=true
    useKeyTab=true
    keyTab="/path/to/client.keytab"
    principal="[email protected]";
};

Refer to the paragraph above to configure the system properties.

Client.java
// Obtain a subject by logging to the KDC using the keytab
LoginContext lc = new LoginContext("HotRodKrbClientWithKeyTab");
lc.login();
Subject subject = lc.getSubject();
// Configure the client for GSSAPI
ConfigurationBuilder config = new ConfigurationBuilder();
config
    .addServer().host("host.address").port(11222)
    .security().authentication().enable()
    .saslMechanism("GSSAPI")
    .clientSubject(subject)
    .serverName("datagrid");
RemoteCacheManager rcm = new RemoteCacheManager(config.build());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment