JWT 身份验证插件
Solr 可以通过使用 JWTAuthPlugin 支持基于 JSON Web Token (JWT) 的 Bearer 身份验证。
这允许 Solr 通过验证 JWT 格式的 访问令牌 是否由身份提供商进行数字签名来断言用户已经通过外部身份提供商进行了身份验证。典型的用例是将 Solr 与启用 OpenID Connect 的 IdP 集成。
模块
这是通过 jwt-auth
Solr 模块 提供的,该模块需要在使用前启用。
启用 JWT 身份验证
要使用 JWT Bearer 身份验证,security.json
文件必须包含 authentication
部分,该部分定义了用于身份验证的类以及配置参数。
用于注册插件的最简单的 security.json
(不带配置)是
{
"authentication": {
"class":"solr.JWTAuthPlugin",
"blockUnknown":"false"
}
}
默认情况下,该插件将需要所有流量的有效 JWT 令牌。
如果如上面的示例中所示,将 blockUnknown
属性设置为 false
,则可以使用未经身份验证的 REST API 调用开始配置插件,这在 编辑 JWT 身份验证插件配置 部分中有进一步的描述。
配置参数
键 | 描述 | 默认值 |
---|---|---|
blockUnknown |
如果您需要通过 REST API 执行配置,或者如果您使用授权插件并且只想保护某些路径,则设置为 |
|
realm |
在 HTTP 401 响应中回显的身份验证域的名称。 也将显示在管理 UI 登录页面中 |
'solr-jwt' |
scope |
以空格分隔的有效范围列表。 如果配置,则 JWT 访问令牌必须包含至少具有列出的范围之一的 |
|
requireIss |
拒绝缺少 |
|
requireExp |
拒绝缺少 |
|
algAllowlist |
包含要接受的算法的 JSON 数组: |
默认值是允许所有算法 |
jwkCacheDur |
JWK 缓存的持续时间(以秒为单位) |
|
principalClaim |
从中提取主体的声明 ID |
|
rolesClaim |
从哪个声明 ID 中提取用户角色。支持顶级声明和嵌套声明。使用 |
默认情况下, |
claimsMatch |
必须与正则表达式(值)匹配的声明(键)的 JSON 对象。示例: |
|
adminUiScope |
定义从管理 UI 登录时请求的范围。 |
如果未定义,则使用 |
redirectUris |
外部身份验证后重定向的有效位置。接受字符串或字符串数组。必须是 Solr 的基本 URL,例如,https://solr1.example.com:8983/solr/ 并且必须与事先在身份提供商处注册的重定向 URI 列表匹配。 |
默认为空列表,即假定任何节点都是有效的重定向目标。 |
trustedCerts |
一个或多个采用纯文本 PEM 或 PKCS#7 格式的 X.509 SSL 证书,在与 IdP 通信时应信任这些证书。换行符必须替换为 |
默认为 Java 信任库。 |
trustedCertsFile |
类型为 PEM、DER 或 PKCS#7 的文件路径,其中包含一个或多个在与 IdP 通信时应信任的 X.509 SSL 证书。也可以是文件路径的数组。有关其用法的更多信息,请参阅 信任 IdP 服务器 段落。 |
默认为 Java 信任库。 |
issuers |
要支持的发行者(身份提供商)列表。有关配置语法,请参阅 发行者配置 部分。 |
发行者配置
此插件支持一个或多个令牌发行者 (IdP)。发行者配置为 issuers
配置键下的 JSON 对象列表。列表中的第一个发行者是“主发行者”,用于登录管理 UI。
键 | 描述 | 默认值 |
---|---|---|
name |
发行者的唯一名称。用于通过 API 操作列表。 |
|
wellKnownUrl |
指向 OpenID Connect Discovery 端点的 URL。 |
|
clientId |
用于 OpenID Connect 的客户端标识符。使用管理 UI 进行身份验证时需要。仅主发行者需要。 |
|
jwksUrl |
指向 JWKs 端点的 URL。必须使用 https 协议。可以选择 URL 数组,在这种情况下,验证签名时将参考来自所有 URL 的所有公钥。 |
如果提供 |
jwk |
作为 |
|
iss |
在 IdP 上配置的唯一发行者 ID。传入令牌必须具有匹配的 |
如果提供 |
aud |
验证 |
如果配置了 |
authorizationEndpoint |
Id 提供商的授权端点的 URL。 |
如果提供 |
tokenEndpoint |
Id 提供商的令牌端点的 URL。 |
如果提供 |
authorizationFlow |
指定要使用的 OAuth 2.0 流。支持的流有“implicit”和“code_pkce”(用于具有“代码交换证明密钥”的授权码)。注意:“implicit”已弃用,强烈建议改用“code_pkce”。 |
implicit |
为了向后兼容,主发行者的所有配置键都可以配置为顶级键,除了 name 。 |
更多配置示例
使用 JWKS URL
要开始对所有用户强制执行身份验证,需要在 Authorization
标头中提供有效的 JWT,您需要使用一个或多个 JSON Web 密钥 (JWK) 配置插件。这是一个包含用于签名/加密 JWT 的密钥的 JSON 文档。它可以是对称或非对称密钥。JWK 可以从外部 HTTPS 端点获取(并缓存),也可以直接在 security.json
中指定。以下是前者的示例
{
"authentication": {
"class": "solr.JWTAuthPlugin",
"jwksUrl": "https://my.key.server/jwk.json"
}
}
支持管理 UI
此示例显示了使用 OpenID Connect Discovery 的配置,其中包含一个众所周知的 URI,用于自动配置许多常见设置,包括使用启用 OpenID Connect 的身份提供商使用管理 UI 的能力。
{
"authentication": {
"class": "solr.JWTAuthPlugin",
"wellKnownUrl": "https://idp.example.com/.well-known/openid-configuration",
"clientId": "xyz",
"redirectUris": "https://my.solr.server:8983/solr/"
}
}
在这种情况下,将从获取的配置中自动配置 jwksUrl
、iss
和 authorizationEndpoint
。
复杂示例
让我们看看一个更复杂的配置,这次配置了两个发行者,其中一个使用静态嵌入的 JWK
{
"authentication": {
"class": "solr.JWTAuthPlugin", (1)
"blockUnknown": true, (2)
"principalClaim": "solruid", (3)
"claimsMatch": { "foo" : "A|B", "dept" : "IT" }, (4)
"scope": "solr:read solr:write solr:admin", (5)
"algAllowlist" : [ "RS256", "RS384", "RS512" ], (6)
"issuers": [ (7)
{
"name": "example1-static", (8)
"jwk": { (9)
"e": "AQAB",
"kid": "k1",
"kty": "RSA",
"n": "3ZF6w....vjbCXxw"
},
"clientId": "solr-client-12345", (10)
"iss": "https://example.com/idp", (11)
"aud": "https://example.com/solr" (12)
},
{
"name": "example2",
"wellKnownUrl": "https://example2.com/.well-known/oidc", (13)
"aud": "https://example2.com/solr"
}
],
"trustedCertsFile": "/path/to/certsFile.pem" (14)
}
}
让我们评论一下这个配置
1 | 插件类 |
2 | 确保阻止任何没有有效令牌的人(这也是默认设置) |
3 | 从默认的 sub 之外的其他声明中获取用户 ID |
4 | 要求 roles 声明为“A”或“B”之一,并且 dept 声明为“IT” |
5 | 要求范围 solr:read 、solr:write 或 solr:admin 之一 |
6 | 仅接受 RSA 算法进行签名 |
7 | 发行者配置数组 |
8 | 每个发行者对象都应具有唯一名称 |
9 | 在这里,我们以内联方式传递 JWK,而不是引用 jwksUrl 的 URL |
10 | 设置在身份提供商处注册的客户端 ID |
11 | 配置发行者 ID。将用于验证令牌。令牌的“iss”声明必须与配置的发行者 ID 之一匹配。 |
12 | 配置受众声明。令牌的“aud”声明必须与配置的发行者之一的“aud”匹配。 |
13 | 此发行者通过发现自动配置,因此不需要“iss”和 JWK 设置 |
14 | 提供 SSL 证书以信任 IdP https 通信。 |
使用非 SSL URL
在生产环境中,您应始终使用受 SSL 保护的 HTTPS 连接,否则您将面临攻击。但是,在开发中,使用常规 HTTP URL 并绕过 Solr 执行的安全检查可能很有用。为了支持这一点,您可以在启动时设置系统属性 -Dsolr.auth.jwt.allowOutboundHttp=true
。
信任 IdP 服务器
与 Oauth2 服务器 (IdP) 的所有通信都通过 HTTPS 完成。默认情况下,使用 Java 的内置信任库。但是,通过配置选项 trustedCertsFile
或 trustedCerts
之一,插件将 改为 信任所提供的一组证书,而不是任何由根 CA 签名的证书。这既更安全,也允许您信任自签名证书。它还具有即使 Solr 未在 SSL 模式下启动也能工作的优点。
请配置 trustedCerts
或 trustedCertsFile
选项。同时配置两者会导致错误。如果 trustedCertsFile
是字符串数组,则 Solr 将从所有文件中解析证书。
多种身份验证方案
Solr 提供 MultiAuthPlugin 以支持基于 Authorization
标头的多种身份验证方案。这允许您配置 Solr 使用 JWTAuthPlugin
将用户管理和身份验证委托给 OIDC 提供商,还允许一小部分服务帐户在不支持或不方便使用 OIDC 时使用 Basic
身份验证。
编辑 JWT 身份验证插件配置
可以使用 身份验证 API 设置或更改上述所有属性。因此,您可以从仅配置了 class
和 blockUnknown=false
的简单配置开始,然后使用 API 配置其余配置。
设置配置属性
设置身份验证插件的属性。上表中每个配置键都可以用作 set-property
命令的参数键。
示例
-
V1 API
-
V2 API
curl https://127.0.0.1:8983/solr/admin/authentication -H 'Content-type:application/json' -H 'Authorization: Bearer xxx.yyy.zzz' -d '{
"set-property": {
"blockUnknown":true,
"wellKnownUrl": "https://example.com/.well-known/openid-configuration",
"scope": "solr:read solr:write"
}
}
'
curl https://127.0.0.1:8983/api/cluster/security/authentication -H 'Content-type:application/json' -H 'Authorization: Bearer xxx.yyy.zzz' -d '{
"set-property": {
"blockUnknown":true,
"wellKnownUrl": "https://example.com/.well-known/openid-configuration",
"scope": "solr:read solr:write"
}
}
'
一旦插件激活,请插入紧凑序列化格式 (xxx.yyy.zzz
以上) 的有效 JWT 访问令牌以使用 Solr 进行身份验证,或者在配置完成之前保留 blockUnknown=false
,然后将其切换为 true
以开始强制执行。
目前不支持通过 REST API 添加多个令牌发行者,但是您可以通过将“发行者”属性用作顶级属性,通过 API 配置单个发行者来解决此问题。 |