Neo4j系列导航:
neo4j安装及简单实践
cypher语法基础
cypher插入语法
cypher插入语法
cypher查询语法
cypher通用语法
cypher函数语法
neo4j索引及调优
1.简介
Kerberos是一种网络身份验证协议,它允许网络节点在网络上证明其身份。它通过使用密钥分发中心(KDC)来确保客户端标识是正确的。除了安全性之外,Kerberos还支持单点登录。这允许在登录到计算机后授予用户对数据库的访问权限,从而为用户提供了简单性。
- Neo4j支持使用Kerberos:4.x、5.x版本支持
2.部署
官方的Neo4j Kerberos Add-on可用于通过Kerberos身份验证扩展Neo4j。该附加组件提供身份验证,并应与其他提供程序(如LDAP)一起用于授权。
- Neo4j Kerberos Add-on v4.0.0与Neo4j的4.x和5.x所有版本兼容
Kerberos Add-on的部署步骤:
将kerberos-add-on.jar文件放在Neo4j安装的plugins/目录中。编辑neo4j.conf以启用Kerberos附加组件作为身份验证提供者。
-
为Kerberos配置Neo4j:
Configure neo4j.conf
#For authentication with kerberos-add-on dbms.security.authentication_providers=plugin-Neo4j-Kerberos dbms.security.authorization_providers=ldap#For authorization with LDAP dbms.security.ldap.host=ad.windomain.local dbms.security.ldap.authorization.use_system_account=true dbms.security.ldap.authorization.system_username=CN=neo4jservice,OU=IT-Services,DC=windomain,DC=local dbms.security.ldap.authorization.system_password=PASSWORD dbms.security.ldap.authorization.user_search_base=CN=Users,DC=windomain,DC=local dbms.security.ldap.authorization.user_search_filter=(&(objectClass=*)(SamAccountName={0})) dbms.security.ldap.authorization.group_membership_attributes=memberOf dbms.security.ldap.authorization.group_to_role_mapping= \"CN=Neo4j Read Only,CN=Users,DC=windomain,DC=local" = reader; \"CN=Neo4j Read-Write,CN=Users,DC=windomain,DC=local" = publisher; \"CN=Neo4j Schema Manager,CN=Users,DC=windomain,DC=local" = architect; \"CN=Neo4j Administrator,CN=Users,DC=windomain,DC=local" = admin; \"CN=Neo4j Procedures,CN=Users,DC=windomain,DC=local" = allowed_role
-
生成Kerberos keytab文件:
为KDC中的Neo4j服务器创建一个服务用户。确保为Neo4j服务用户生成一个keytab,并将其放在conf目录中。在本例中,我们将其命名为neo4j.ktab。keytab将被Neo4j使用。 -
配置Kerberos Add-on:
如果您已经通过Heimdal或MIT工具套件使用Kerberos,那么您有一个krb5.conf文件,其中包含有关如何访问KDC的信息。如果您没有这样的文件,或者不希望使用它,请在conf目录中创建一个新的krb5.conf文件。配置krb5.conf:
在本例中,我们使用的是WINDOMAIN领域。LOCAL和KDC和管理服务器的IP地址192.168.38.2。将它们分别替换为KDC和管理服务器的实际领域和实际IP或域名。[libdefaults] default_realm = WINDOMAIN.LOCALdefault_tgs_enctypes = rc4-hmac rc4-hmac-exp aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha1-96 des3-hmac-sha1 default_tkt_enctypes = rc4-hmac rc4-hmac-exp aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha1-96 des3-hmac-sha1 permitted_enctypes = rc4-hmac rc4-hmac-exp aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha1-96 des3-hmac-sha1[realms] WINDOMAIN.LOCAL = {kdc = 192.168.38.2admin_server = 192.168.38.2 }[domain_realm] .windomain.local = WINDOMAIN.LOCAL windomain.local = WINDOMAIN.LOCAL
Java本身不支持某些加密算法。当使用更高级的加密算法(例如ASE-256)时,确保运行Neo4j的Java启用了Java Cryptography Extension扩展。
现在在conf目录中创建第二个名为kerberos.conf的文件。keytab设置引用上面创建的keytab文件。该服务。主体设置是该keytab中的主体,krb5.conf设置引用krb5.conf文件(已经从现有Kerberos安装中存在,或者在上面步骤中创建)。同样,根据您的设置将这些值替换为正确的值。
配置kerberos.conf:
realm=WINDOMAIN.LOCAL keytab=conf/neo4j.ktab service.principal=neo4j/neo4j.windomain.local@WINDOMAIN.LOCAL krb5.conf=conf/krb5.conf
3.使用
要使用Kerberos进行身份验证的客户机应用程序代码必须针对KDC进行身份验证,并获取Neo4j服务的服务票证(在我们的示例中:Neo4j /neo4j.windomain.local@WINDOMAIN.LOCAL)。服务ticket必须直接或封装在SPNEGO(1.3.6.1.5.5.2)中使用Kerberos v5(1.2.840.113554.1.2.2)机制。
服务ticket应该以以下属性的认证令牌形式提供给Neo4j驱动程序:
- Principal: empty
- Credentials: the Base64-encoded service ticket
- Realm: add-on-Neo4j-Kerberos
Kerberos Add-on目前不能与Neo4j浏览器一起工作。它
只适用于使用Neo4j驱动程序的应用程序
。
实例一:Java驱动
使用1.3 Java驱动程序的示例实现
public void connect()
{byte[] serviceTicket = get(serviceDomainName);String scheme = "ticket";String realm = "add-on-Neo4j-Kerberos";String encodedServiceTicket = Base64.getEncoder().encodeToString( serviceTicket );AuthToken token = AuthTokens.custom( encodedServiceTicket );try ( Driver driver = GraphDatabase.driver( "bolt://" + serviceDomainName, token ) ){// do interesting things}
}public byte[] get(String serviceDomainName) throws LoginException, GSSException
{Map<String,String> options = Collections.singletonMap( "useTicketCache", "true" );Krb5Configuration loginContextConfiguration = new Krb5Configuration( options );LoginContext loginContext = new LoginContext("KerberosClient",null, // this is the subjectnull, // no need for thisloginContextConfiguration);loginContext.login();return getServiceTicket( loginContext.getSubject(), "neo4j@" + serviceDomainName );
}
public static final Oid SPNEGO_OID = getOid( "1.3.6.1.5.5.2" );
public byte[] getServiceTicket(Subject subject, String servicePrincipalName) throws GSSException
{GSSManager manager = GSSManager.getInstance();GSSName serverName = manager.createName( servicePrincipalName, GSSName.NT_HOSTBASED_SERVICE );final GSSContext context = manager.createContext(serverName, SPNEGO_OID, null, GSSContext.DEFAULT_LIFETIME );// The GSS context initiation has to be performed as a privileged action.return Subject.doAs( subject, new PrivilegedAction<byte[]>(){public byte[] run(){try{// This is a one pass context initialisation.context.requestMutualAuth( false );context.requestCredDeleg( false );return context.initSecContext( new byte[0], 0, 0 );}catch ( GSSException e ){e.printStackTrace();return null;}}} );
}private class Krb5Configuration extends Configuration
{private final AppConfigurationEntry[] configList;public Krb5Configuration( Map<String,String> options ){this.configList = new AppConfigurationEntry[1];configList[0] =new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,options);}@Overridepublic AppConfigurationEntry[] getAppConfigurationEntry(String name){return configList;}
}
实例一:c#驱动
使用c#和1.3 . net驱动程序实现的示例
var token = AuthTokens.kerberos(getTicket("neo4j"));using (var driver = GraphDatabase.Driver("bolt://neo4j.windomain.local:7687", token)){try{using (var session = driver.Session()){var result = session.Run("MATCH () RETURN count(*) AS count");foreach (var record in result){Console.WriteLine($"Nodecount: {record["count"].As<string>()}");}}}catch (Exception e){Console.WriteLine($"Error: {e.Message}");}
}private static String getTicket(string serviceName){AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);var domain = Domain.GetCurrentDomain().ToString();using (var domainContext = new PrincipalContext(ContextType.Domain, domain)){string spn = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, serviceName).UserPrincipalName;Console.WriteLine("Service Principale name: " + spn);KerberosSecurityTokenProvider tokenProvider = new KerberosSecurityTokenProvider(spn);KerberosRequestorSecurityToken securityToken = tokenProvider.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;var token = securityToken.GetRequest();String ticket = Convert.ToBase64String(token);return ticket;}}