Geode集群双向SSL环境下基于证书DN的认证实现问询
基于双向SSL证书DN的Geode认证授权实现方案
核心思路
Geode默认的用户名密码认证体系未直接暴露证书信息,但可通过扩展内置安全接口,从SSL连接中提取证书DN完成认证,再基于该DN做授权校验。
实现方向1:自定义SecurityManager获取SSL证书
Geode的SecurityManager接口的authenticate方法可通过ConnectionContext参数拿到底层SSL会话,进而提取证书信息:
步骤1:实现自定义SecurityManager
import org.apache.geode.security.SecurityManager; import org.apache.geode.security.AuthenticationFailedException; import javax.net.ssl.SSLSession; import java.security.cert.X509Certificate; import java.util.Properties; public class DNBasedSecurityManager implements SecurityManager { @Override public Object authenticate(Properties props, ConnectionContext context) throws AuthenticationFailedException { // 从ConnectionContext获取SSL会话 SSLSession sslSession = context.getSSLSession(); if (sslSession == null) { throw new AuthenticationFailedException("双向SSL未启用,无法获取证书"); } try { // 获取客户端证书链 X509Certificate[] certs = (X509Certificate[]) sslSession.getPeerCertificates(); if (certs.length == 0) { throw new AuthenticationFailedException("未提供客户端证书"); } // 解析证书DN并校验CN字段 String dn = certs[0].getSubjectDN().getName(); if (!dn.contains("cn=example.com")) { throw new AuthenticationFailedException("证书CN不符合要求"); } // 返回DN作为身份标识,供后续授权使用 return dn; } catch (Exception e) { throw new AuthenticationFailedException("证书认证失败", e); } } @Override public boolean authorize(Object principal, ResourcePermission permission) { // 基于DN做授权校验,示例:仅允许指定DN的主体执行操作 String dn = (String) principal; return dn.contains("cn=example.com"); } }
步骤2:配置Geode启用自定义SecurityManager
在geode.properties中添加:
security-manager=com.yourcompany.DNBasedSecurityManager # 确保双向SSL基础配置已完成(keystore/truststore等) ssl-enabled=true ssl-require-authentication=true
实现方向2:使用CertificateAuthenticator接口(Geode 1.10+)
Geode 1.10及以上版本提供了CertificateAuthenticator接口,专门用于证书认证,逻辑更简洁:
步骤1:实现CertificateAuthenticator
import org.apache.geode.security.CertificateAuthenticator; import org.apache.geode.security.AuthenticationFailedException; import java.security.cert.X509Certificate; import java.util.Properties; public class DNCertificateAuthenticator implements CertificateAuthenticator { @Override public void init(Properties props) {} @Override public Object authenticate(X509Certificate[] certs) throws AuthenticationFailedException { if (certs == null || certs.length == 0) { throw new AuthenticationFailedException("无客户端证书"); } String dn = certs[0].getSubjectDN().getName(); if (!dn.contains("cn=example.com")) { throw new AuthenticationFailedException("无效证书CN"); } // 返回DN作为身份标识 return dn; } @Override public void close() {} }
步骤2:配置启用
在geode.properties中添加:
security-certificate-authenticator=com.yourcompany.DNCertificateAuthenticator ssl-enabled=true ssl-require-authentication=true # 搭配SecurityManager完成授权逻辑 security-manager=com.yourcompany.DNBasedSecurityManager
授权环节补充说明
- 认证通过后,返回的DN(或提取的CN)会作为
principal传入SecurityManager.authorize方法,可基于该值配置细粒度权限,比如允许特定DN的节点加入集群、允许特定客户端读写指定区域。 - 可将DN映射为内部角色(例如把
cn=example.com映射为ADMIN角色),再通过Geode的security-permissions.xml配置文件分配对应权限。
内容的提问来源于stack exchange,提问作者NoName
相关产品推荐
相关产品推荐

