配置 OAuth 身份验证
有关 ODBC OAuth 连接属性的列表,请参阅 ODBC DSN 连接属性。
以下过程将:
-
配置 Keycloak 18.0。
-
创建 OAuth 身份验证记录。
-
使用 POST 请求检索访问令牌。
-
使用示例应用程序 sample application 向 Vertica 验证身份,并将访问令牌作为实参和令牌刷新参数(可选)传递。
配置 keycloak
以下过程将在 203.0.113.1 上配置 Keycloak 18.0.0 服务器。
使用 TLS(可选)
如果要使用 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
-
输入以下命令获取最小配置,以创建 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 分钟)。
创建 Vertica 客户端
-
导航到客户端 (Clients) 并单击创建 (Create)。此时会显示添加客户端 (Add Client) 页面。
-
在客户端 ID (Client ID) 中,输入
vertica
。 -
单击保存 (Save)。此时会显示客户端配置页面。
-
在设置 (Settings) 选项卡中,使用访问类型 (Access Type) 下拉菜单选择机密 (confidential)。
-
在凭据 (Credentials) 选项卡中,记下密码 (Secret)。这是用于在令牌过期时刷新令牌的客户端密码。
创建 Keycloak 用户
Keycloak 用户可映射到同名的 Vertica 用户。此示例创建了一个 Keycloak 用户 oauth_user
。
-
在用户 (Users) 选项卡中,单击添加用户 (Add user)。此时会显示添加用户 (Add user) 页面。
-
在用户名 (Username) 中,输入
oauth_user
。 -
在凭据 (Credentials) 选项卡中,输入密码。
配置 Vertica
创建身份验证记录
为 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 用户
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
ODBC
-
遵循 README 中的说明。
-
运行示例应用程序,同时将 OAuth 参数作为实参传递:
-
在令牌过期之前进行身份验证:
$ ./a.out --access-token OAuthAccessToken
-
在访问令牌过期后进行身份验证并静默刷新访问令牌:
$ ./a.out --access-token OAuthAccessToken --refresh-token OAuthRefreshToken --client-id OAuthClientID --client-secret OAuthClientSecret --token-url OAuthTokenURL
-
JDBC
-
遵循 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
标记。
将 CA 证书导入 Java 信任库
如果您通过 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