使用 Worker 自动将您身份提供商最新的公钥保持在 JWT 验证配置中。
- 找到您的区域 ID。您可以在 Cloudflare 仪表板 ↗的区域概述中找到此 ID。
- 找到您的身份提供商的 JSON Web 密钥集 (JWKs) URL。身份提供商通常会在开放授权 (OAuth) 设置中列出它。
- 创建一个令牌验证配置。
- 创建一个新的 API 令牌 ↗,具有 API Gateway
Write权限。
您必须手动查询 JWKs 端点,以确保 JWKs 存在于预期的位置和格式中。然后,创建一个 Worker 来自动更新 JWKs,并创建一个 Worker 机密 (Worker Secret) 来存放用于更新 API Shield 设置的 API 密钥。然后,您可以安排该 Worker 定期自动更新 JWKs。
找到您的身份提供商的 URL,并使用 curl 和 jq 获取密钥。您的 URL 可能会返回不仅仅是签发者的密钥,因此 Cloudflare 建议使用 jq 来过滤响应以仅返回密钥。如果您的 JWKs 没有 keys 对象,您必须更新提供的 Worker 示例代码。
curl https://<your-team-name>.cloudflareaccess.com/cdn-cgi/access/certs -s | jq .keys[
{
"kid": "ca96ae653935dbfb49b4e19de600cc5f9d5c63e3ac2dbee406ed4bf0ae100cce",
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"e": "AQAB",
"n": "9dG9Ph4ffncvEA9FO9pVMfJ1dh_5mtuyiIE4ap9ScrufVPq1I34St_dhcFavKiytK7Id7gTlgQgaouoJ0I5OJ_bytgX-B7oOUQHO-nJOAMycORXN8ZNaMBPKg9nBLL_BFY0YX5HggqrkXkZjJ--R4JpB30ENS8A6hxmEJ__yGMZTE2LHZoiYj9iyGNu3s3JflAoRlmziI8LsFXwyFAJUWRZq4SkSfyrRJ89pXPxIqBn9uYBtnxWzUpWG3xKZu0JAbi9YiwFCJrSe_CarvpARoWsOldtrty5yT1yJ1PZlImlF-yuEwjOoZxeib4WSidABZH0O3pbDACo8MfxR5rghHQ"
},
{
"kid": "1e590a6dcd60e3e2306c21eca19144c59d591531267a3ebde8d521f40894329d",
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"e": "AQAB",
"n": "6uj6PgDq-bPsdFjiQ6M3yaxMxBUnnYj20xtLciHNafqrygAjnZKjl8LfCO_mtZ7jxfJNCARsz0L3sF9LAtARZqcsUvYLUlNDzflwNTe8woCT7yw0Ml2ZV5BWDbc3izEQnvjlBDGWv9p5jv-D-YNExtIzZKsRKyoy7hSu5FhyxmPfiAXo8b67f0dNy8V8HZfQJ5i9VGyK4Z5xKM-FjHOrC2uIbhzUE6wDe_0M23RTCxj7ZxzXUzZzc-_EBjmZDAI3tI2zBYymO55_gw8zHrNsZ4-32YvNTjBAiTLsjvKlsvNtPTN8q3saoZJWQMSiMi8dRalgA6pUDgcNs5lB9E7tWw"
}
]-
将下面的示例代码复制并粘贴到您的新 Worker 中,完全替换已存在的任何代码。
-
将当前的区域 ID 替换为您的区域 ID。
-
将当前的令牌验证配置 ID 替换为您的令牌验证配置。
-
将当前身份提供商的 URL 替换为您的身份提供商的密钥 URL。
-
如果您的 JWKs URL 在
keys以外的任何 JSON 对象中返回密钥,请更新fetchCredentials()函数以仅返回密钥数据。 -
选择 Create(创建) > Deploy(部署)。
-
在 Worker 设置中,转到 Variables(变量) 并添加一个名为
CF_API_TOKEN的环境变量,其值为您创建的 API 令牌。 -
在 Worker 触发器中,为该 Worker 分配一个 cron 触发器。Cloudflare 建议频繁的更新间隔,以确保您始终拥有最新密钥,并使身份提供商立即进行的密钥轮换造成的停机时间最短。
JavaScript 示例代码js /** * 更新令牌验证凭据 (Update Token Validation Credentials) * * 此示例显示了如何使用 Cloudflare Workers cron 触发器 * 来自动轮换令牌配置的 JWKs。 * * 要配置此 Worker: * * 1. 将 `token_config_id` 替换为要更新的 Token Config 的 ID * 2. 将 `zone_id` 替换为您的 Zone ID * 3. 将 `url` 替换为包含要使用的 JWKs 的可公开访问的 URL * 4. 创建一个具有 "Zone.API Gateway Edit" 权限的新 API 令牌,并将其作为名为 `CF_API_TOKEN` 的机密添加(参见 https://developers.cloudflare.com/workers/configuration/secrets/) * * 此 worker 还处理 GET 和 POST 请求: * - GET 将从提供的 URL 获取并显示凭证 (`GET https://random-worker-name-c134.example.workers.dev/`) * - POST 触发更新并返回该更新的 Cloudflare API 响应 (`POST https://random-worker-name-c134.example.workers.dev/`) * * 使用这些请求来测试 Worker 是否正确配置。 * * 设置好 worker 后,您可以创建一个 cron 触发器来定期运行它。 * 有关 cron 触发器的更多信息,请参阅 https://developers.cloudflare.com/workers/configuration/cron-triggers/ * * 在 https://developers.cloudflare.com/workers/ 了解有关 Workers 的更多信息。 */ var zone_id = "760549bc17c54280d6e6ae256c3dd6ae"; var token_config_id = "91007e72-8f17-46b7-a223-5e57bd333b78"; var url = "https://cfdata.cloudflareaccess.com/cdn-cgi/access/certs"; // JWKs /** * fetchCredentials 使用上面定义的 URL 获取新的令牌配置凭据。 * 这会返回一个包含凭据的 JSON 字符串。 * * 使用此函数获取并解析凭据。 * * @returns {string} credentials */ async function fetchCredentials() { var requestOptions = { method: "GET", redirect: "follow", }; const keys = await fetch(url, requestOptions) .then((e) => e.json()) .then((e) => e.keys); return JSON.stringify({ keys: keys }); } /** * updateCredentials 使用 Cloudflare API 更新令牌配置凭据。 * 凭据是使用 fetchCredentials 获取的,该函数还会进行任何所需的处理。 * * @param {string} bearer 具有 "Zone.API Gateway Edit" 权限的 Cloudflare API Bearer 令牌 * @returns {string} 来自更新请求的 Cloudflare API 响应 */ async function updateCredentials(bearer) { // 用于凭证更新的 Cloudflare API 端点 const url = `https://api.cloudflare.com/client/v4/zones/${zone_id}/token_validation/config/${token_config_id}/credentials`; const init = { body: await fetchCredentials(), method: "PUT", headers: { Authorization: `Bearer ${bearer}`, "content-type": "application/json;charset=UTF-8", }, }; const response = await fetch(url, init); return response.text(); } // 导出包含事件处理程序的默认对象 export default { /** * fetch 处理直接对 Worker 发起的请求。 * */ async fetch(request, env, ctx) { let responseBody = ""; if (request.method === "GET") { responseBody = await fetchCredentials(); } else if (request.method === "POST") { responseBody = await updateCredentials(env.CF_API_TOKEN); } return new Response(responseBody, { headers: { "content-type": "application/json;charset=UTF-8" }, }); }, /** * scheduled 是 cron 触发器的处理程序。 * * 详情请参阅 https://developers.cloudflare.com/workers/configuration/cron-triggers/ * */ async scheduled(request, env, ctx) { ctx.waitUntil(updateCredentials(env.CF_API_TOKEN)); }, };