As you may already be familiar based on the comments in your question above, I encourage you to first re-review the section on SSL in the Security chapter of Apache Geode's documentation. SSL would be a prerequisite for everything I am about to suggest below.
Apache Geode's Security implementation of Authentication (as well as Authorization) is based on Apache Geode's SecurityManager
interface as well as the AuthInitialize
interface.
The SecurityManager
is used on the server-side to authenticate clients (or additional peers joining the P2P cluster as a member). An implementation of the AuthInitialize
interface is used by clients (or other peers joining the P2P cluster as a member) to supply the credentials.
The supplied SecurityManager
implementation is configured with the [gemfire.]security-manager
property. The AuthInitialize
implementation is configured with the [gemfire.]security-client-auth-init
property (or the [gemfire.]security-peer-auth-init
property).
While Apache Geode's documentation commonly refers to username/password-based authentication for Geode nodes (clients and peers), the fact of the matter is, the Properties
returned by the (client-side) AuthInitialize.getCredentials(..)
(Javadoc) method and processed on the server-side, SecurityManager.authenticate(:Properties)
(Javadoc) could contain the appropriate certificate and evidence as described (for example) here.
It is not uncommon for Password-based authentication to be used with Certificate-based authentication (both over SSL).
In which, case you could do the following. On the client-side:
package example.app.geode.security.client.auth;
import org.apache.geode.security.AuthInitialize;
class CertificateBasedAuthInitialize implements AuthInitialize {
public static CertificateBasedAuthInitialize create() {
new CertificateBasedAuthInitialize();
}
public Properties getCredentials(Properties securityProperties, DistributedMember member, boolean isServer) {
Properties credentials = new Properties(securityProperties);
// Load PrivateKey from KeyStore using java.security API.
PrivateKey privateKey = ...
Certificate clientCertificate = privateKey.getCertificate();
// Sign the some randomly generated data with the PrivateKey.
Object signedEvidence = ...
credentials.put("certificate", clientCertificate);
credentials.put("evidence", signedEvidence);
// optional...
credentials.put(AuthInitialize.SECURITY_USERNAME, username);
credentials.put(AuthInitialize.SECURITY_PASSWORD, password);
return credentials;
}
}
Then configure your client with:
# Spring Boot application.properties
spring.data.gemfire.security.client.authentication-initializer=\
example.app.geode.security.client.auth.CertificateBasedAuthInitialize.create
...
The server-side, custom SecurityManager
implementation would then use the credentials to authenticate the client.
package example.app.geode.security.server.auth;
import org.apache.geode.security.SecurityManager;
class CertificateBasedSecurityManager implements SecurityManager {
public Object authenticate(Properties securityProperties) {
Certificate certificate = securityProperties.get("certificate");
Objected signedEvidence = securityProperties.get("evidence");
// verify the client's cert and use the PublicKey to verify the "evidence".
}
}
If the servers's in the Apache Geode cluster were configured and bootstrapped with Spring, then you would configure your custom SecurityManager
implementation using:
# Spring Boot application.properties
spring.data.gemfire.security.manager.class-name=\
example.app.geode.security.server.auth.CertificateBasedSecurityManager
If you used Gfsh to start the Locators and Servers in your cluster, then refer to Apache Geode's documentation to configure properties on startup.
As you may also be aware (based on your tags), Apache Geode integrates with Apache Shiro. Unfortunately, I did not find any support in Apache Shiro for Certificate-based Authentication (here), which introduces the concept of Realms
for auth, where the available Realms
provided by Apache Shiro are here (you can see support for ActiveDirectory, JDBC, JNDI, LDAP, and text-based Realms
).
Of course, you could also devise an implementation of Apache Geode's SecurityManager
interface along with the AuthInitialize
interface, integrated with Spring Security and follow the general advice in Baeldung's blog post.
Hopefully this gives you enough to think about and some ideas on how to go about implementing Certificate-based Authentication between clients and servers (and peers?) in your [Spring] Apache Geode application/cluster.