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 |
与 IdP 通信时应受信任的一个或多个 X.509 SSL 证书,采用纯文本 PEM 或 PKCS#7 格式。换行符必须替换为 |
默认为 Java 信任库 |
trustedCertsFile |
包含一个或多个 X.509 SSL 证书的 PEM、DER 或 PKCS#7 类型文件的路径,在与 IdP 通信时应信任这些证书。还可以是文件路径数组。有关其用法,请参阅信任 IdP 服务器段落。 |
默认为 Java 信任库 |
issuers |
要支持的发行者(身份提供者)列表。有关配置语法,请参阅发行者配置部分 |
发行者配置
此插件支持一个或多个令牌发行者(IdP)。发行者在issuers
配置键下配置为 JSON 对象列表。列表中的第一个发行者是“主要发行者”,它用于登录到管理 UI。
密钥 | 说明 | 默认值 |
---|---|---|
name |
发行者的唯一名称。用于通过 API 操作列表。 |
|
wellKnownUrl |
指向OpenID Connect Discovery端点的 URL |
|
clientId |
用于 OpenID Connect 的客户端标识符。需要使用管理 UI 进行身份验证。仅适用于主要发行者 |
|
jwksUrl |
指向JWK端点的 URL。必须使用 https 协议。或者,也可以使用 URL 数组,在这种情况下,在验证签名时将参考所有 URL 中的所有公钥。 |
如果提供了 |
jwk |
作为 |
|
iss |
在 IdP 上配置的唯一发行者 ID。传入令牌必须具有匹配的 |
如果提供了 |
aud |
验证 |
如果已配置,则使用 |
authorizationEndpoint |
Id 提供者授权端点的 URL |
如果提供了 |
tokenEndpoint |
Id 提供者令牌端点的 URL |
如果提供了 |
authorizationFlow |
指定要使用的 OAuth 2.0 流程。支持的流程为“implicit”和“code_pkce”(用于带有“Proof Key for Code Exchange”的授权码)。注意:“implicit”已弃用,强烈建议改用“code_pkce”。 |
implicit |
为了向后兼容,主要发行者的所有配置键都可以配置为顶级键,name 除外。 |
更多配置示例
使用 JWKS URL
要开始对所有用户强制执行身份验证,要求在 Authorization
头中提供有效的 JWT,您需要使用一个或多个 JSON Web Key(JWK)来配置插件。这是一份包含用于对 JWT 进行签名/加密的密钥的 JSON 文档。它可以是对称密钥或非对称密钥。JWK 可以从外部 HTTPS 端点获取(并缓存)或直接在 security.json
中指定。以下是一个前者的示例
{
"authentication": {
"class": "solr.JWTAuthPlugin",
"jwksUrl": "https://my.key.server/jwk.json"
}
}
使用 Admin UI 支持
此示例显示了使用 OpenID Connect Discovery 的配置,其中有一个众所周知的 URI,用于自动配置许多常见设置,包括使用具有 OpenID Connect 启用的身份提供程序的 Admin 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 的内置 TrustStore。但是,通过配置选项 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
curl http://localhost: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"
}
}
'
V2 API
curl http://localhost: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"
}
}
'
在插件处于活动状态后,插入一个有效的 JWT 访问令牌(紧凑序列化格式,如上文中的 xxx.yyy.zzz
)以使用 Solr 进行身份验证,或将 blockUnknown=false
保留到配置完成,然后将其切换为 true
以开始强制执行。
目前不支持通过 REST API 添加多个令牌颁发者,但是您可以通过使用“颁发者”属性作为顶级属性通过 API 配置单个颁发者来解决此问题。 |