高级连接信息
连接协议与安全性
驱动程序与服务器之间的通信由 Bolt 进行中介。服务器 URI 的方案(scheme)决定了连接是否加密,以及如果加密,接受何种类型的证书。
| URL 方案 | 加密 | 注释 |
|---|---|---|
neo4j |
本地设置的默认值 |
|
neo4j+s |
(仅限 CA 签名的证书) |
Aura 的默认值 |
neo4j+ssc |
(CA 签名和自签名证书) |
无论实例是适当的集群环境还是单机环境,驱动程序在成功连接后都会从服务器接收一张路由表。驱动程序的路由行为通过将读/写事务引导至适当的集群成员,与 Neo4j 集群配合工作。如果您想针对特定机器,请改用 bolt、bolt+s 或 bolt+ssc URI 方案。 |
要使用的连接方案并非由您选择,而是由服务器要求决定的。您必须预先知道正确的服务器方案,因为在连接之前不会公开任何元数据。连接方案是实例 URI 的一部分。如果不确定,请咨询数据库管理员。
身份验证方法
基本身份验证(默认)
基本身份验证方案依赖于传统的用户名和密码。
from neo4j import GraphDatabase
driver = GraphDatabase.driver(URI, auth=(USERNAME, PASSWORD))
基本身份验证方案也可用于针对 LDAP 服务器进行身份验证(仅限企业版)。
Kerberos 身份验证
Kerberos 身份验证方案需要一个 base64 编码的票据。只有在服务器安装了 Kerberos 插件的情况下才能使用。
from neo4j import GraphDatabase, kerberos_auth
driver = GraphDatabase.driver(URI, auth=kerberos_auth(ticket))
Bearer 身份验证
Bearer 身份验证方案需要由身份提供商通过 Neo4j 的 单点登录功能 (Single Sign-On feature) 提供的 base64 编码令牌。
from neo4j import GraphDatabase, bearer_auth
driver = GraphDatabase.driver(URI, auth=bearer_auth(token))
| Bearer 身份验证方案需要 在服务器上配置单点登录。配置完成后,客户端可以通过 发现 API (Discovery API) 获取 Neo4j 的配置信息。 |
自定义身份验证
使用函数 custom_auth 登录到具有自定义身份验证方案的服务器。
轮换身份验证令牌
可以轮换预期会过期的身份验证令牌(例如 SSO)。运行时间长于令牌有效期的事务将继续运行,而无需重新进行身份验证,而同一会话中的不同事务可能在不同的身份验证令牌下工作。
若要处理轮换令牌(rotating tokens),在实例化 Driver 时,您需要提供一个 AuthManager 实例(或者针对异步驱动程序的 AsyncAuthManager),而不是使用静态身份验证令牌。最简单的入门方法是使用 内置的 AuthManager 实现之一。
import neo4j
from neo4j.auth_management import (
AuthManagers,
ExpiringAuth,
)
def auth_provider():
# Some way to get a token
sso_token = get_sso_token()
# Assume we know tokens expire every 60 seconds
expires_in = 60
# Include a little buffer so that new token is fetched before the old one expires
expires_in -= 10
auth = neo4j.bearer_auth(sso_token)
return ExpiringAuth(auth=auth).expires_in(expires_in)
with neo4j.GraphDatabase.driver(
URI,
auth=AuthManagers.bearer(auth_provider)
) as driver:
...
AuthManagers(包括传递给 AuthManagers.expiration_based() 的提供程序函数)不得以任何方式与驱动程序交互,因为这可能导致死锁和未定义的行为。 |
双向 TLS(客户端证书作为双因素认证)Aura 不支持
双向 TLS (mTLS) 允许您使用客户端证书作为向服务器进行身份验证的第二因素。除非服务器上禁用了身份验证,否则该证书只能与身份验证令牌一起使用,不能替代常规身份验证。
客户端的证书和公钥必须放置在服务器的 <NEO4J_HOME>/certificates/bolt/trusted 目录中。有关服务器设置的更多信息,请参阅 配置 Bolt 上的 SSL。
要使 mTLS 工作,驱动程序与服务器的连接必须加密,即 连接 URI 方案 必须为 +s 或 +ssc(例如 neo4j+s://example.com:7687)。 |
使用 ClientCertificateProviders.static() 处理静态证书。
该方法接收一个 ClientCertificate 实例,其参数与 Python 的 ssl.SSLContext.load_cert_chain() 相同。
import neo4j
from neo4j.auth_management import (
ClientCertificate,
ClientCertificateProviders,
)
URI = "<database-uri>"
AUTH = ("<username>", "<password>")
cert_provider = ClientCertificateProviders.static(
ClientCertificate(
# path to certificate
"path/to/cert.pem",
# path to private key (optional; needed if certificate does not contain private key too)
"path/to/key.pem",
# password to decrypt private key (can be function or string) (optional)
lambda: "password",
)
)
with neo4j.GraphDatabase.driver(
URI,
auth=AUTH,
client_certificate=cert_provider,
) as driver:
...
使用 ClientCertificateProviders.rotating() 处理轮换证书。
该方法接收一个 ClientCertificate 实例。
import neo4j
from neo4j.auth_management import (
ClientCertificate,
ClientCertificateProviders,
)
URI = "<database-uri>"
AUTH = ("<username>", "<password>")
cert_provider = ClientCertificateProviders.rotating(
ClientCertificate(
# path to public certificate to load
"path/to/cert.pem",
# path to private key to load
"path/to/key.pem",
# password to decrypt private key (can be a function or string)
# see also Python's ssl.SSLContext.load_cert_chain()
lambda: "password",
)
)
driver = neo4j.GraphDatabase.driver(
URI
auth=(USERNAME, PASSWORD),
client_certificate=cert_provider
)
# use the driver...
# ... until the certificate needs to be rotated
cert_provider.update_certificate(
ClientCertificate(
certfile="path/to/new/cert.pem",
keyfile="path/to/new/key.pem",
password=lambda: "new_super_secret_password"
)
)
# use the driver again, until the certificate needs to be
# rotated again
# ...
有关更多信息,请参阅 API 文档 → ClientCertificateProvider。
自定义地址解析器
创建 Driver 对象时,您可以指定一个解析器 (resolver) 函数,以便在 DNS 解析之前解析驱动程序接收到的任何地址。您的解析器函数将接收一个 Address 对象,并应返回一个可迭代的 Address 对象(或可用于构建 Address 对象的值)。
自定义地址解析器无法更改 URI 方案(下例中的 neo4j://)。 |
9999 上对 example.com 的连接被解析为端口 7687 上的 localhostimport neo4j
def custom_resolver(socket_address):
# assert isinstance(socket_address, neo4j.Address)
if socket_address != ("example.com", 9999):
raise OSError(f"Unexpected socket address {socket_address!r}")
# You can return any neo4j.Address object
yield neo4j.Address(("localhost", 7687)) # IPv4
yield neo4j.Address(("::1", 7687, 0, 0)) # IPv6
yield neo4j.Address.parse("localhost:7687")
yield neo4j.Address.parse("[::1]:7687")
# or any tuple that can be passed to neo4j.Address().
# This will initially be interpreted as IPv4, but DNS resolution
# will turn it into IPv6 if appropriate.
yield "::1", 7687
# This will be interpreted as IPv6 directly, but DNS resolution will
# still happen.
yield "::1", 7687, 0, 0
yield "127.0.0.1", 7687
driver = neo4j.GraphDatabase.driver("neo4j://example.com:9999",
auth=(USERNAME, PASSWORD),
resolver=custom_resolver)
禁用遥测
如果服务器有要求,驱动程序可以将匿名使用统计信息发送到其连接的服务器。遥测在服务器端通过配置设置 server.bolt.telemetry.enabled 进行管理。默认情况下,自管理实例上的遥测是禁用的,Aura 实例上的遥测是启用的。
通过在连接时设置 telemetry_disabled=True,驱动程序将永远不会发送任何遥测数据。
import neo4j
driver = neo4j.GraphDatabase.driver(URI, auth=(USERNAME, PASSWORD), telemetry_disabled=True)
有关传输信息的更多信息,请参阅 API 文档 → telemetry_disabled。
其他连接参数
您可以在 API 文档 中找到所有的 Driver 配置参数。
术语表
- LTS (长期支持版)
-
长期支持 (Long Term Support) 版本是保证在若干年内得到支持的版本。Neo4j 4.4 和 5.26 是 LTS 版本。
- Aura
-
Aura 是 Neo4j 的全托管云服务。它提供免费和付费计划。
- Cypher
-
Cypher 是 Neo4j 的图查询语言,允许您从数据库中检索数据。它就像 SQL,但专用于图数据库。
- APOC
-
Awesome Procedures On Cypher (APOC) 是一个包含(许多)函数的库,这些函数在 Cypher 本身中难以轻松实现。
- Bolt
-
Bolt 是用于 Neo4j 实例和驱动程序之间交互的协议。默认监听 7687 端口。
- ACID
-
原子性 (Atomicity)、一致性 (Consistency)、隔离性 (Isolation)、持久性 (Durability) (ACID) 是保证数据库事务可靠处理的属性。符合 ACID 的 DBMS 确保即使发生故障,数据库中的数据也能保持准确和一致。
- 最终一致性
-
如果一个数据库能保证所有集群成员在某个时间点都存储了数据的最新版本,则该数据库具有最终一致性。
- 因果一致性
-
如果读写查询被集群中的每个成员以相同的顺序看到,则数据库具有因果一致性。这比最终一致性更强。
- NULL
-
空标记不是一种类型,而是缺失值的占位符。更多信息,请参阅 Cypher → 使用
null。 - 事务
-
事务是一个工作单元,要么被提交,要么在失败时被回滚。例如银行转账:它涉及多个步骤,但它们必须全部成功或全部撤销,以避免钱从一个账户扣除却未存入另一个账户的情况。
- 背压
-
背压是对数据流的抵抗力。它确保客户端不会被过快发送的数据压垮,从而超出其处理能力。
- 书签
-
书签是代表数据库某种状态的标记。通过将一个或多个书签与查询一起传递,服务器将确保在所表示的状态建立之前,该查询不会被执行。
- 事务函数
-
事务函数是由
execute_read或execute_write调用执行的回调。如果发生服务器故障,驱动程序会自动重新执行该回调。 - 驱动程序 (Driver)
-
一个
Driver对象保存了与 Neo4j 数据库建立连接所需的详细信息。