OIDC 认证
SelectDB Enterprise 可以作为 OAuth 2.0 Resource Server,验证身份提供商(Identity Provider,IdP)为 Doris 签发的 access token,并将外部身份映射到 Doris 用户和角色。
该功能自 SelectDB Enterprise 4.1.4 起支持。
OIDC 认证包括以下步骤:
- 验证 JWT 的签名以及
iss、aud、exp、nbf等 claim。 - 将外部身份映射为 Doris principal。
- 根据角色映射规则为当前会话授予 Doris 角色。
请使用为 Doris 资源端签发的 access token。不要将浏览器登录流程返回的 ID token 直接用于 Doris 认证。
前提条件
开启 SSL
OIDC 登录要求 FE 开启 SSL。在 fe.conf 中设置:
enable_ssl = true
如需校验客户端证书,可以同时设置:
ssl_force_client_auth = true
修改配置后重启 FE。客户端必须启用 SSL:MySQL Shell 至少使用 --ssl-mode=REQUIRED,Connector/J 至少设置 sslMode=REQUIRED。
安装支持 OIDC 的客户端
可以使用以下客户端通过 OIDC 登录:
- MySQL Shell 9.x(
mysqlsh)。 - MySQL Connector/J 9.1.0 或更高版本。
普通 mysql 命令行客户端、低版本 MySQL Shell 和低版本 Connector/J 不支持当前 OIDC 登录方式。
使用 MySQL Shell 时,执行以下命令确认版本:
mysqlsh --version
准备 access token
IdP 签发的 token 需要满足以下要求:
- 使用 Doris 支持的非对称算法签名。
- 包含
iss、aud和expclaim。 - 如果包含
nbf,token 必须已生效。 oidc.username_claim和oidc.subject_claim指定的 claim 必须存在。oidc.username_claim的值必须与客户端连接时使用的 Doris 用户名一致。- 如果配置了
oidc.required_scopes,token 必须包含所有指定 scope。 - 如果配置了
oidc.allowed_client_ids,token 中的azp或client_id必须匹配允许列表。当两者同时存在时,优先使用azp。
OIDC 认证支持以下签名算法:
RS256、RS384、RS512PS256、PS384、PS512ES256、ES384、ES512
配置 OIDC 认证集成
使用 CREATE AUTHENTICATION INTEGRATION 创建 OIDC 认证集成。
参数说明
| 参数 | 是否必填 | 说明 |
|---|---|---|
type | 是 | 认证插件类型。OIDC 认证固定设置为 oidc。 |
oidc.issuer | 是 | token 的预期 issuer,必须与 iss claim 完全匹配。 |
oidc.jwks_uri | 是 | IdP 的 JSON Web Key Set(JWKS)地址,用于验证 token 签名。 |
oidc.allowed_audiences | 是 | 允许的 audience,多个值以逗号分隔。token 的 aud 必须至少匹配一个值。 |
enable_jit_user | 否 | 是否为不存在的 Doris 用户启用即时(JIT)用户接入。该参数是认证集成的通用参数。 |
oidc.required_scopes | 否 | token 必须包含的 scope,多个值以逗号分隔。 |
oidc.allowed_client_ids | 否 | 允许的客户端 ID,多个值以逗号分隔。 |
oidc.username_claim | 否 | 用作 Doris 登录名的 claim。 |
oidc.subject_claim | 否 | 用作外部主体标识的 claim。 |
oidc.groups_claim | 否 | 包含外部用户组的 claim。该 claim 可以是字符串或字符串数组。 |
oidc.extra_claims | 否 | 提供给角色映射规则的额外 claim,多个值以逗号分隔。 |
oidc.allowed_algorithms | 否 | 允许的 JWT 签名算法,多个值以逗号分隔。 |
oidc.clock_skew_seconds | 否 | 校验 token 时间 claim 时允许的时钟偏差,单位为秒。 |
scope 和 scp claim 可以是字符串或数组。字符串会按空白字符拆分为多个 scope。
创建最小配置
CREATE AUTHENTICATION INTEGRATION partner_oidc
PROPERTIES (
'type' = 'oidc',
'oidc.issuer' = 'https://idp.example.com/realms/doris',
'oidc.jwks_uri' = 'https://idp.example.com/realms/doris/protocol/openid-connect/certs',
'oidc.allowed_audiences' = 'doris-prod'
);
生产环境通常还需要限制 scope、客户端 ID 和签名算法,并配置身份 claim:
CREATE AUTHENTICATION INTEGRATION partner_oidc
PROPERTIES (
'type' = 'oidc',
'enable_jit_user' = 'true',
'oidc.issuer' = 'https://idp.example.com/realms/doris',
'oidc.jwks_uri' = 'https://idp.example.com/realms/doris/protocol/openid-connect/certs',
'oidc.allowed_audiences' = 'doris-prod',
'oidc.required_scopes' = 'doris.query',
'oidc.allowed_client_ids' = 'grafana-doris-plugin',
'oidc.username_claim' = 'preferred_username',
'oidc.subject_claim' = 'sub',
'oidc.groups_claim' = 'doris_groups',
'oidc.extra_claims' = 'tenant,email',
'oidc.allowed_algorithms' = 'RS256',
'oidc.clock_skew_seconds' = '60'
);
创建后,可以查询系统表确认配置是否正确保存:
SELECT name, type, properties, comment
FROM information_schema.authentication_integrations
WHERE name = 'partner_oidc';
配置认证链
OIDC 认证集成通过 FE 配置项 authentication_chain 加入认证链。例如:
authentication_chain = partner_oidc
如果同时使用密码、LDAP 等其他认证方式,请根据预期认证顺序将对应项保留在认证链中。
复用已有 Doris 用户时,需要确保:
- Doris 中已存在对应用户。
- token 中用户名 claim 的值与 Doris 用户名一致。
- 目标 OIDC 认证集成已加入
authentication_chain。
配置角色映射
认证集成负责判断 token 是否可以登录;角色映射负责确定认证成功后为会话授予哪些 Doris 角色。
先创建角色并授予所需权限,再使用 CREATE ROLE MAPPING 创建映射:
CREATE ROLE analyst;
CREATE ROLE finance_reader;
CREATE ROLE MAPPING partner_oidc_roles
ON AUTHENTICATION INTEGRATION partner_oidc
RULE (
USING CEL 'attr("oauth.client_id") == "grafana-doris-plugin"'
GRANT ROLE analyst
),
RULE (
USING CEL 'has_group("doris_finance_reader")'
GRANT ROLE finance_reader
);
建议使用稳定的用户组、客户端 ID 或业务 claim(例如 tenant、environment)设计授权规则。如果 scope 仅用于控制是否可以访问 Doris,建议通过 oidc.required_scopes 在认证阶段校验。
使用 MySQL Shell 登录
保存 access token
将原始 access token 保存到本地文件。文件中只包含 token 文本,不要包含 JSON 包装或 ID token。例如:
eyJraWQiOiJrZXktMSIsImFsZyI6IlJTMjU2In0...
请限制 token 文件的访问权限,并在 token 过期后及时替换或删除。
建立连接
mysqlsh --sql --sqlc --ssl-mode=REQUIRED \
-h <fe_host> -P 9030 -u alice \
--authentication-openid-connect-client-id-token-file=/path/to/alice.access_token \
-e "SELECT CURRENT_USER();"
验证服务端证书时,使用:
mysqlsh --sql --sqlc --ssl-mode=VERIFY_CA \
--ssl-ca=/path/to/ca.pem \
-h <fe_host> -P 9030 -u alice \
--authentication-openid-connect-client-id-token-file=/path/to/alice.access_token \
-e "SELECT CURRENT_USER();"
登录后执行以下语句验证用户和权限:
SELECT CURRENT_USER();
SHOW GRANTS;
使用 JDBC 登录
MySQL Connector/J 9.1.0 及更高版本支持 OIDC 认证。连接必须使用 SSL,并通过 idTokenFile 指定 token 文件的绝对路径。
idTokenFile 是 Connector/J 的参数名。该文件仍应保存面向 Doris 签发的 access token,而不是浏览器登录流程返回的 ID token。
token 文件必须满足以下要求:
- 使用绝对路径。
- 文件在应用运行时存在且可读。
- 文件大小不超过 10 KiB。
- 文件中只包含原始 access token,不包含 JSON 包装。
使用 Properties 配置
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
String url = "jdbc:mysql://127.0.0.1:9030/test";
Properties props = new Properties();
props.setProperty("user", "alice");
props.setProperty(
"defaultAuthenticationPlugin",
"authentication_openid_connect_client");
props.setProperty("idTokenFile", "/absolute/path/to/alice.access_token");
props.setProperty("sslMode", "REQUIRED");
try (Connection connection = DriverManager.getConnection(url, props);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT CURRENT_USER()")) {
while (resultSet.next()) {
System.out.println(resultSet.getString(1));
}
}
参数说明:
| 参数 | 说明 |
|---|---|
user | Doris 登录用户名,必须与 oidc.username_claim 对应的 token claim 一致。 |
defaultAuthenticationPlugin | 显式指定 Connector/J 使用 authentication_openid_connect_client 插件。 |
idTokenFile | access token 文件的绝对路径。 |
sslMode | OIDC 要求使用安全连接。设置为 REQUIRED 时强制使用 SSL,但不校验服务端证书。 |
使用 JDBC URL(Driver URI)配置
也可以将相同参数直接写入 JDBC URL。部分连接池或配置中心将该字段称为 Driver URL 或 Driver URI:
import java.sql.Connection;
import java.sql.DriverManager;
String url = "jdbc:mysql://127.0.0.1:9030/test"
+ "?user=alice"
+ "&defaultAuthenticationPlugin=authentication_openid_connect_client"
+ "&idTokenFile=/absolute/path/to/alice.access_token"
+ "&sslMode=REQUIRED";
try (Connection connection = DriverManager.getConnection(url)) {
// 使用 connection 执行查询。
}
如果 token 路径或其他参数值包含空格、& 等 URL 特殊字符,需要对参数值进行 URL 编码。
配置证书校验
sslMode=REQUIRED 会强制加密连接,但不会校验服务端证书,适用于使用自签名证书的测试环境。无需额外设置 allowCustomHostnameVerification 或 trustServerCertificate。
生产环境建议将签发 FE 证书的 CA 导入 Java truststore,并使用 VERIFY_CA 或 VERIFY_IDENTITY:
props.setProperty("sslMode", "VERIFY_IDENTITY");
props.setProperty(
"trustCertificateKeyStoreUrl",
"file:/absolute/path/to/truststore.p12");
props.setProperty("trustCertificateKeyStoreType", "PKCS12");
props.setProperty("trustCertificateKeyStorePassword", "<password>");
VERIFY_CA:验证服务端证书是否由受信任 CA 签发。VERIFY_IDENTITY:在VERIFY_CA的基础上验证证书中的主机名。
有关 Connector/J OIDC 和 SSL 参数的完整说明,请参阅 MySQL Connector/J OpenID Connect 文档,以及 MySQL Connector/J SSL 文档。
常见问题
无法建立 OIDC 连接
检查以下配置:
fe.conf中已设置enable_ssl = true,并已重启 FE。- MySQL Shell 使用
--ssl-mode=REQUIRED或更严格的模式,Connector/J 使用sslMode=REQUIRED或更严格的模式。 - 使用的是 MySQL Shell 9.x 或 Connector/J 9.1.0 及更高版本。
token 校验失败
确认传入的是面向 Doris 签发的 access token,并检查以下内容:
iss和aud是否与认证集成配置匹配。- token 是否已过期或尚未生效。
scope、azp或client_id是否满足限制。- JWT 签名算法是否在允许列表中。
用户名不匹配
检查 oidc.username_claim 指定的 claim,并确保其值与 MySQL Shell 的 -u 参数或 Connector/J 的 user 参数一致。复用本地用户时,还需要确保 Doris 中存在同名用户。
登录成功但权限不符合预期
检查以下内容:
- 角色映射规则是否命中 token 中的用户组、客户端 ID 或额外 claim。
oidc.groups_claim和oidc.extra_claims是否配置正确。- 映射授予的 Doris 角色是否拥有目标对象权限。
可以查询 information_schema.role_mappings 核对已保存的规则,再通过 SHOW GRANTS 检查当前会话角色。