用户无需使用用户名和密码即可向 Vertica 验证身份,具体操作为:首先通过身份提供程序验证其身份,然后接收 OAuth 令牌并将令牌传递给 Vertica。
Vertica 中的 OAuth 通过 Keycloak 和 Okta 进行测试,但如果其他提供程序支持 RFC 7662 令牌自省标准,也可以使用。
用户无需使用用户名和密码即可向 Vertica 验证身份,具体操作为:首先通过身份提供程序验证其身份,然后接收 OAuth 令牌并将令牌传递给 Vertica。
Vertica 中的 OAuth 通过 Keycloak 和 Okta 进行测试,但如果其他提供程序支持 RFC 7662 令牌自省标准,也可以使用。
有关 ODBC OAuth 连接属性的列表,请参阅 ODBC DSN 连接属性。
以下过程将:
配置 Keycloak 18.0。
创建 OAuth 身份验证记录。
使用 POST 请求检索访问令牌。
使用示例应用程序 sample application 向 Vertica 验证身份,并将访问令牌作为实参和令牌刷新参数(可选)传递。
以下过程将在 203.0.113.1 上配置 Keycloak 18.0.0 服务器。
如果要使用 TLS,您必须获取由受信任的 CA 签名的 Keycloak 证书和密钥。为方便起见,此示例将使用自签名 CA。
生成 CA 证书:
=> CREATE KEY SSCA_key TYPE 'RSA' LENGTH 2048;
CREATE KEY
=> CREATE CA CERTIFICATE SSCA_cert
SUBJECT '/C=US/ST=Massachusetts/L=Cambridge/O=Micro Focus/OU=Vertica/C N=Vertica Root CA'
VALID FOR 3650
EXTENSIONS 'nsComment' = 'Self-signed root CA cert'
KEY SSCA_key;
CREATE CERTIFICATE
生成由您的 CA 签名的服务器密钥和证书,将证书的 subjectAltName 设置为您的 Keycloak 服务器的 DNS 和/或 IP 地址:
=> CREATE KEY keycloak_key TYPE 'RSA' LENGTH 2048;
CREATE KEY
=> CREATE CERTIFICATE keycloak_cert
SUBJECT '/C=US/ST=Massachussets/L=Cambridge/O=Micro Focus/OU=Vertica/CN=Vertica Server'
SIGNED BY SSCA_cert
EXTENSIONS 'nsComment' = 'Keycloak CA', 'extendedKeyUsage' = 'serverAuth', 'subjectAltName' = 'DNS.1:dnsserver,IP:203.0.113.1'
KEY keycloak_key;
CREATE CERTIFICATE
使用生成的密钥的 key
列内容创建文件
keycloak_directory/conf/keyfile.pem
:
=> SELECT key FROM cryptographic_keys WHERE name = 'keycloak_key';
使用生成的证书的 certificate_text
列内容创建文件
keycloak_directory/conf/certfile.pem
:
=> SELECT certificate_text FROM certificates WHERE name = 'keycloak_cert';
将生成的 CA 证书的 certificate_text
列内容附加到系统的 CA 捆绑包中。默认 CA 捆绑包路径和格式因分发版而异;有关详细信息,请参阅 SystemCABundlePath:
=> SELECT certificate_text FROM certificates WHERE name = 'SSCA_cert';
设置 SystemCABundlePath 配置参数:
=> ALTER DATABASE DEFAULT SET SystemCABundlePath = 'path/to/ca_bundle';
输入以下命令获取最小配置,以创建 Keycloak 管理员并在 start-dev 模式下启动 Keycloak:
$ KEYCLOAK_ADMIN=kcadmin
$ export KEYCLOAK_ADMIN
$ KEYCLOAK_ADMIN_PASSWORD=password
$ export KEYCLOAK_ADMIN_PASSWORD
$ cd keycloak_directory/bin/
$ ./kc.sh start-dev --hostname 203.0.113.1 --https-certificate-file ../conf/certfile.pem --https-certificate-key-file=../conf/keyfile.pem
使用浏览器打开 Keycloak 控制台(这些示例使用默认端口):
对于 HTTP:http://203.0.113.1:8080
对于 HTTPS:http://203.0.113.1:8443
以管理员身份登录。
(可选)为了更加方便地测试 OAuth,请导航到领域设置 (Realm Settings) > 令牌 (Tokens),然后将访问令牌生命期 (Access Token Lifespan) 增加到更大的值(默认值为 5 分钟)。
导航到客户端 (Clients) 并单击创建 (Create)。此时会显示添加客户端 (Add Client) 页面。
在客户端 ID (Client ID) 中,输入
vertica
。
单击保存 (Save)。此时会显示客户端配置页面。
在设置 (Settings) 选项卡中,使用访问类型 (Access Type) 下拉菜单选择机密 (confidential)。
在凭据 (Credentials) 选项卡中,记下密码 (Secret)。这是用于在令牌过期时刷新令牌的客户端密码。
Keycloak 用户可映射到同名的 Vertica 用户。此示例创建了一个 Keycloak 用户 oauth_user
。
在用户 (Users) 选项卡中,单击添加用户 (Add user)。此时会显示添加用户 (Add user) 页面。
在用户名 (Username) 中,输入 oauth_user
。
在凭据 (Credentials) 选项卡中,输入密码。
为 OAuth 创建身份验证记录。
以下
身份验证记录v_oauth
使用 OAuth 令牌(而不是用户名和密码)对来自任何 IP 地址的用户进行身份验证,并且使用以下参数。身份提供者是 Keycloak 18.0.0:
client_id
:机密客户端
vertica
在 Keycloak 中注册。
client_secret
:客户端密钥,由 Keycloak 生成。
discovery_url
:也称为 OpenID 提供者配置文档,这是包含有关身份提供者的配置和端点的信息的端点。
=> CREATE AUTHENTICATION v_oauth METHOD 'oauth' HOST '0.0.0.0/0'
=> ALTER AUTHENTICATION v_oauth SET client_id = 'vertica';
=> ALTER AUTHENTICATION v_oauth SET client_secret = 'client_secret';
=> ALTER AUTHENTICATION v_oauth SET discovery_url = 'https://203.0.113.1:8443/realms/myrealm/.well-known/openid-configuration';
=> ALTER AUTHENTICATION v_oauth SET introspect_url = 'https://203.0.113.1:8443/realms/myrealm/protocol/openid-connect/token/introspect';
Vertica 用户可映射到用户名相同的 Keycloak 用户。
要映射到 Keycloak 用户 oauth_user
,请创建一个同名的 Vertica 用户。无需指定密码,因为身份验证由身份提供程序执行:
=> CREATE USER oauth_user;
将 OAuth 身份验证记录授予用户(或其角色):
=> GRANT AUTHENTICATION v_oauth TO oauth_user;
=> GRANT ALL ON SCHEMA PUBLIC TO oauth_user;
获取 OAuth 访问令牌的一种简单方法是将 POST 请求发送到令牌端点,同时提供 Keycloak 用户的凭据。例如,oauth_user
:
$ curl --location --request POST 'http://203.0.113.1:8080/realms/master/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=oauth_user' \
--data-urlencode 'password=oauth_user_password' \
--data-urlencode 'client_id=vertica' \
--data-urlencode 'client_secret=client_secret' \
--data-urlencode 'grant_type=password'
如果身份验证正确,Keycloak 会以 JSON 的格式作出响应。然后,您可以将返回的访问令牌、刷新令牌和范围与相应的连接属性一起使用。
{
"access_token":"access_token",
"expires_in":60,
"refresh_expires_in":1800,
"refresh_token":"refresh_token",
"token_type":"Bearer",
"not-before-policy":0,
"session_state":"6745892a-aa74-452f-b6b9-c45637193859",
"scope":"profile email"
}
在令牌过期之前,OAuth 示例应用程序至少会将访问令牌作为实参来对数据库进行身份验证。如果您希望示例应用程序在令牌过期后刷新令牌,您必须指定以下内容。示例应用程序会将这些内容放入 JSON
字符串:OAuthJsonConfig 或 (ODBC) oauthjsonconfig (JDBC)。
刷新令牌
客户端 ID
客户端密码
令牌 URL
遵循 README 中的说明。
运行示例应用程序,同时将 OAuth 参数作为实参传递:
在令牌过期之前进行身份验证:
$ ./a.out --access-token OAuthAccessToken
在访问令牌过期后进行身份验证并静默刷新访问令牌:
$ ./a.out --access-token OAuthAccessToken
--refresh-token OAuthRefreshToken
--client-id OAuthClientID
--client-secret OAuthClientSecret
--token-url OAuthTokenURL
遵循 README 中的说明。
运行示例应用程序,同时将 OAuth 参数作为实参传递:
在令牌过期之前进行身份验证:
$ mvn compile exec:java -Dexec.mainClass=OAuthSampleApp -Dexec.args="vertica_host database_name --access-token oauthaccesstoken"
在访问令牌过期后进行身份验证并静默刷新访问令牌:
$ mvn compile exec:java -Dexec.mainClass=OAuthSampleApp -Dexec.args="vertica_host database_name --access-token oauthaccesstoken
--refresh_token oauthrefreshtoken
--client-id oauthclientid
--client-secret oauthclientsecret
--token-url oauthtokenurl"
要获取 TLS 的调试信息,请使用 -Djavax.net.debug=ssl
标记。
如果您通过 TLS 配置身份提供程序(即,如果您对令牌或刷新 URL 使用 HTTPS 端点),且其证书不是由熟知的 CA 颁发的,则必须使用 keytool
导入颁发机构的 CA 证书。
例如,将证书 keycloak/cert.crt
添加到 Java 信任库:
$ keytool -trustcacerts -keystore /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.261-2.6.22.2.el7_8.x86_64/jre/lib/security/cacerts -storepass changeit -importcert -alias keycloak -file /keycloak/cert.crt