HTMLTAG_67__HTMLTAG_68___1。帶有 Keycloak 的 API 閘道模式___HTMLTAG_69__HTMLTAG_70
在微服務架構中,API 閘道可作為所有客戶端請求的單一入口點。與 Keycloak 結合使用時,閘道可處理 集中式驗證 和 JWT 傳播 到下游服務。
預編碼_0
___HTMLTAG_79__HTMLTAG_80___網關___HTMLTAG_81__HTMLTAG_82___驗證方法___HTMLTAG_83__HTMLTAG_84___優點____HTMLTAG_85__HTMLTAG_86___ ___HTMLTAG_89__HTMLTAG_90___Nginx + lua-resty-openidc___HTMLTAG_91__HTMLTAG_92___Lua模組OIDC___HTMLTAG_93__HTMLTAG_94___輕量級、高效能___HTMLTAG95__1TAG_96___ ___HTMLTAG_97__HTMLTAG_98___Nginx + OAuth2 代理___HTMLTAG_99__HTMLTAG_100___Sidecar 代理___HTMLTAG_101__HTMLTAG_102___設定簡單,不需 Lua____HTMLTAG_101__HTMLTAG_102___設定簡單,不需 Lua____HTMLTAG_103__41TAG_103__4 ___HTMLTAG_105__HTMLTAG_106___Kong Gateway___HTMLTAG_107__HTMLTAG_108___OIDC插件____HTMLTAG_109__HTMLTAG_110___企業功能、插件生態系統____HTMLTAG_111__HTMLTAG_112___ ___HTMLTAG_113__HTMLTAG_114___Traefik____HTMLTAG_115__HTMLTAG_116___ForwardAuth___HTMLTAG_117__HTMLTAG_118___雲原生、自動發現___HTMLTAG_119__HTMLTAG_120___HTMLTAG_123__HTMLTAG_124___2。 Nginx + Keycloak 整合___HTMLTAG_125__HTMLTAG_126
HTMLTAG_127__HTMLTAG_128___2.1 方法 1:lua-resty-openidc___HTMLTAG_129__HTMLTAG_130
___HTMLTAG_131__HTMLTAG_132___lua-resty-openidc 是 Nginx/OpenResty 的 OpenID Connect 模組,直接在 Nginx 層支援 JWT 驗證、令牌自省和 OIDC 登入流程。
2.1.1 安裝 OpenResty
預編碼_1
2.1.2 具有不記名令牌驗證的 Nginx 設定__HTMLTAG_138___
預編碼_2
HTMLTAG_139__HTMLTAG_140___2.2 方法 2:OAuth2 代理 Sidecar___HTMLTAG_141__HTMLTAG_142
___HTMLTAG_143__HTMLTAG_144___oauth2-proxy 是一個反向代理,透過 OAuth2/OIDC 提供者提供驗證。這種方法不需要 Lua 並且更容易設定:
預編碼_3
2.2.1 OAuth2 代理程式設定__HTMLTAG_148___
預編碼_4
2.2.2 Nginx 與 auth_request
預編碼_5
HTMLTAG_151__HTMLTAG_152___3。 Kong網關+鑰匙斗篷___HTMLTAG_153__HTMLTAG_154
HTMLTAG_155__HTMLTAG_156___3.1 Kong OIDC插件配置___HTMLTAG_157__HTMLTAG_158
Kong Gateway 支援 OIDC 外掛程式(Kong Enterprise 或社群外掛程式)來驗證來自 Keycloak 的 JWT 令牌:
預編碼_6
HTMLTAG_161__HTMLTAG_162___3.2 Kong 管理 API 設定___HTMLTAG_163__HTMLTAG_164
透過 Kong 管理 API 而非宣告式進行設定:
預編碼_7
HTMLTAG_167__HTMLTAG_168___4。 Traefik + Keycloak___HTMLTAG_169__HTMLTAG_170
HTMLTAG_171__HTMLTAG_172___4.1 ForwardAuth 中間件___HTMLTAG_173__HTMLTAG_174
Traefik 使用 ForwardAuth 中間件 將身分驗證委託給外部服務(OAuth2 代理):
預編碼_8
預編碼_9
HTMLTAG_179__HTMLTAG_180___4.2 帶有 Docker 標籤的 Traefik___HTMLTAG_181__HTMLTAG_182
預編碼_10
HTMLTAG_183__HTMLTAG_184___5。服務帳戶驗證___HTMLTAG_185__HTMLTAG_186
HTMLTAG_187__HTMLTAG_188___5.1 客戶憑證授予___HTMLTAG_189__HTMLTAG_190
對於服務到服務通訊(沒有使用者上下文),請使用 客戶端憑證授予:
┌──────────────┐ ┌──────────────┐
│ Service A │ │ Keycloak │
│ (Order) │ │ │
│ │── 1. client_id ───▶│ │
│ │ + client_secret │ │
│ │ │ │
│ │◀── 2. Access ──────│ │
│ │ Token │ │
└──────┬───────┘ └──────────────┘
│
│ 3. Bearer token
▼
┌──────────────┐
│ Service B │
│ (Payment) │
│ │
└──────────────┘
5.1.1 Keycloak 客戶端設定__HTMLTAG_196___
Client Settings cho Service Account:
Client ID: order-service
Client Protocol: openid-connect
Access Type: confidential
Service Accounts: ON
Standard Flow: OFF (không cần user login)
Direct Access: OFF
Service Account Roles:
→ Assign realm roles hoặc client roles cần thiết
→ Ví dụ: payment-read, payment-write
Client Settings cho Service Account:
Client ID: order-service
Client Protocol: openid-connect
Access Type: confidential
Service Accounts: ON
Standard Flow: OFF (không cần user login)
Direct Access: OFF
Service Account Roles:
→ Assign realm roles hoặc client roles cần thiết
→ Ví dụ: payment-read, payment-write
5.1.2 取得服務帳號代幣
# Client Credentials Grant
curl -s -X POST \
"http://localhost:8080/realms/my-realm/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=order-service" \
-d "client_secret=order-service-secret" \
| jq .
# Response:
# {
# "access_token": "eyJhbGci...",
# "expires_in": 300,
# "token_type": "Bearer",
# "not-before-policy": 0,
# "scope": "profile email"
# }
5.1.3 Spring Boot 中的服務帳戶
package com.example.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.time.Instant;
import java.util.Map;
@Service
public class ServiceAccountTokenProvider {
@Value("${keycloak.auth-server-url}")
private String keycloakUrl;
@Value("${keycloak.realm}")
private String realm;
@Value("${keycloak.service-account.client-id}")
private String clientId;
@Value("${keycloak.service-account.client-secret}")
private String clientSecret;
private final RestTemplate restTemplate = new RestTemplate();
private String cachedToken;
private Instant tokenExpiry;
public synchronized String getServiceAccountToken() {
// Return cached token nếu còn hạn
if (cachedToken != null && Instant.now().isBefore(tokenExpiry)) {
return cachedToken;
}
// Request new token
String tokenUrl = String.format(
"%s/realms/%s/protocol/openid-connect/token",
keycloakUrl, realm
);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type", "client_credentials");
body.add("client_id", clientId);
body.add("client_secret", clientSecret);
HttpEntity<MultiValueMap<String, String>> request =
new HttpEntity<>(body, headers);
ResponseEntity<Map> response = restTemplate.postForEntity(
tokenUrl, request, Map.class
);
Map<String, Object> tokenResponse = response.getBody();
cachedToken = (String) tokenResponse.get("access_token");
int expiresIn = (Integer) tokenResponse.get("expires_in");
// Refresh 30 giây trước khi hết hạn
tokenExpiry = Instant.now().plusSeconds(expiresIn - 30);
return cachedToken;
}
}
// Sử dụng service account token để gọi downstream service
@Service
public class PaymentServiceClient {
private final RestTemplate restTemplate = new RestTemplate();
private final ServiceAccountTokenProvider tokenProvider;
public PaymentServiceClient(ServiceAccountTokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
public PaymentResult processPayment(PaymentRequest request) {
String token = tokenProvider.getServiceAccountToken();
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(token);
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<PaymentRequest> entity = new HttpEntity<>(request, headers);
ResponseEntity<PaymentResult> response = restTemplate.exchange(
"http://payment-service:8083/api/payments",
HttpMethod.POST,
entity,
PaymentResult.class
);
return response.getBody();
}
}
___HTMLTAG_201__HTMLTAG_202___5.2 令牌交換 (RFC 8693)HTMLTAG_203__HTMLTAG_204
令牌交換允許服務將使用者令牌交換為具有不同範圍/受眾的新令牌,或在呼叫下游服務時模擬使用者:
# Bật Token Exchange trong Keycloak
# Realm Settings → Token → Token Exchange: Enable
# Exchange user token thành service-specific token
curl -s -X POST \
"http://localhost:8080/realms/my-realm/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "client_id=order-service" \
-d "client_secret=order-service-secret" \
-d "subject_token=$USER_ACCESS_TOKEN" \
-d "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
-d "audience=payment-service" \
-d "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
| jq .
# Response chứa token mới với audience = payment-service
# Token vẫn giữ user identity nhưng scoped cho payment-service
Luồng Token Exchange:
User ──▶ Order Service (user token)
│
├── Exchange user token → Keycloak
│ (audience = payment-service)
│
◀── New token (user context, scoped for payment)
│
├── Call Payment Service (exchanged token)
│
◀── Payment result
HTMLTAG_207__HTMLTAG_208___5.3 內部服務驗證模式___HTMLTAG_209__HTMLTAG_210
___HTMLTAG_213__HTMLTAG_214___模式____HTMLTAG_215__HTMLTAG_216___用例___HTMLTAG_217__HTMLTAG_218_______HTMLTAG_219__HTMLTAG_220________HTMLTAG2121_____ ___HTMLTAG_225__HTMLTAG_226___JWT 傳播___HTMLTAG_227__HTMLTAG_228___將使用者令牌轉送至下游___HTMLTAG_229__HTMLTAG_230___簡單,保留使用者上下文___HT ___HTMLTAG_235__HTMLTAG_236___客戶端憑證___HTMLTAG_237__HTMLTAG_238___服務到服務,無使用者上下文____HTMLTAG_239__HTMLTAG_240___獨立於使用者工作階段____HTMLTAG_241__4UG_241__41424UU42____ML41__4U424141____ ___HTMLTAG_245__HTMLTAG_246___令牌交換____HTMLTAG_247__HTMLTAG_248___模擬、受眾限制____HTMLTAG_249__HTMLTAG_250___使用者上下文+範圍存取____HTMLTAG_2511HTMLTAG_250___用戶上下文+範圍存取____HTMLTAG_2511HTMLTAG_250___ML ___HTMLTAG_255__HTMLTAG_256___mTLS___HTMLTAG_257__HTMLTAG_258___零信任服務網格___HTMLTAG_259__HTMLTAG_260___強身份,無需令牌____HTMLTAG_261_HTMLTAGML_262_______MLTAGML42_____HTMLTAG_267__HTMLTAG_268___6。完整的 Docker Compose 堆疊___HTMLTAG_269__HTMLTAG_270
Docker Compose 堆疊配有 Keycloak、PostgreSQL、Nginx 閘道和後端服務:
# docker-compose.yml
version: '3.9'
services:
# ===== PostgreSQL Database =====
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: keycloak_password
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U keycloak"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
# ===== Keycloak =====
keycloak:
image: quay.io/keycloak/keycloak:25.0
command: start-dev --import-realm
environment:
KC_DB: postgres
KC_DB_URL_HOST: postgres
KC_DB_URL_DATABASE: keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: keycloak_password
KC_HOSTNAME: localhost
KC_HOSTNAME_PORT: 8080
KC_HTTP_ENABLED: "true"
KC_HEALTH_ENABLED: "true"
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
volumes:
- ./keycloak/realm-export.json:/opt/keycloak/data/import/realm-export.json
ports:
- "8080:8080"
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "exec 3<>/dev/tcp/localhost/8080 && echo -e 'GET /health/ready HTTP/1.1\r\nHost: localhost\r\n\r\n' >&3 && cat <&3 | grep -q '200'"]
interval: 30s
timeout: 10s
retries: 5
networks:
- backend
# ===== API Gateway (Nginx + OAuth2 Proxy) =====
oauth2-proxy:
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
command:
- --provider=keycloak-oidc
- --provider-display-name=Keycloak
- --oidc-issuer-url=http://keycloak:8080/realms/my-realm
- --client-id=oauth2-proxy-client
- --client-secret=oauth2-proxy-secret
- --cookie-secret=bXktMzItYnl0ZS1iYXNlNjQtZW5jb2RlZC1zZWNyZXQ=
- --cookie-secure=false
- --email-domain=*
- --upstream=static://202
- --http-address=0.0.0.0:4180
- --set-xauthrequest=true
- --pass-access-token=true
- --pass-authorization-header=true
- --skip-auth-route=^/api/public/
- --skip-provider-button=true
depends_on:
keycloak:
condition: service_healthy
networks:
- backend
nginx:
image: nginx:1.27-alpine
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
ports:
- "80:80"
depends_on:
- oauth2-proxy
- user-service
- order-service
networks:
- backend
# ===== Backend Services =====
user-service:
build:
context: ./services/user-service
dockerfile: Dockerfile
environment:
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: http://keycloak:8080/realms/my-realm
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: http://keycloak:8080/realms/my-realm/protocol/openid-connect/certs
SERVER_PORT: 8081
ports:
- "8081:8081"
depends_on:
keycloak:
condition: service_healthy
networks:
- backend
order-service:
build:
context: ./services/order-service
dockerfile: Dockerfile
environment:
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: http://keycloak:8080/realms/my-realm
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: http://keycloak:8080/realms/my-realm/protocol/openid-connect/certs
SERVER_PORT: 8082
# Service account cho gọi payment-service
KEYCLOAK_SERVICE_ACCOUNT_CLIENT_ID: order-service
KEYCLOAK_SERVICE_ACCOUNT_CLIENT_SECRET: order-service-secret
ports:
- "8082:8082"
depends_on:
keycloak:
condition: service_healthy
networks:
- backend
volumes:
postgres_data:
networks:
backend:
driver: bridge
HTMLTAG_273__HTMLTAG_274___6.1 Docker Compose 的 Nginx 設定____HTMLTAG_275__HTMLTAG_276
# nginx/conf.d/default.conf
upstream user-service {
server user-service:8081;
}
upstream order-service {
server order-service:8082;
}
upstream oauth2-proxy {
server oauth2-proxy:4180;
}
server {
listen 80;
server_name localhost;
# ===== OAuth2 Proxy endpoints =====
location /oauth2/ {
proxy_pass http://oauth2-proxy;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Auth-Request-Redirect $request_uri;
}
location = /oauth2/auth {
proxy_pass http://oauth2-proxy;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Content-Length "";
proxy_pass_request_body off;
}
# ===== Public APIs (no auth) =====
location /api/public/ {
proxy_pass http://user-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# ===== Protected: User APIs =====
location /api/users {
auth_request /oauth2/auth;
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-User $user;
proxy_set_header X-Email $email;
proxy_set_header Authorization "Bearer $token";
error_page 401 = /oauth2/sign_in;
proxy_pass http://user-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# ===== Protected: Order APIs =====
location /api/orders {
auth_request /oauth2/auth;
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header Authorization "Bearer $token";
error_page 401 = /oauth2/sign_in;
proxy_pass http://order-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# ===== Health check =====
location /health {
return 200 '{"status":"UP"}';
add_header Content-Type application/json;
}
}
HTMLTAG_277__HTMLTAG_278___7。監控與速率限制___HTMLTAG_279__HTMLTAG_280
HTMLTAG_281__HTMLTAG_282___7.1 監控服務帳號代幣___HTMLTAG_283__HTMLTAG_284
預編碼_20
HTMLTAG_285__HTMLTAG_286___7.2 服務帳戶最佳實務___HTMLTAG_287__HTMLTAG_288
___HTMLTAG_291__HTMLTAG_292___#___HTMLTAG_293__HTMLTAG_294___練習___HTMLTAG_295__HTMLTAG_296___說明___HTMLTAG_297__HTMLTAG_298___ ___HTMLTAG_301__HTMLTAG_302___1___HTMLTAG_303__HTMLTAG_304___短期令牌___HTMLTAG_305__HTMLTAG_306___為服務帳戶設定存取權杖短生命週期(5 分鐘)____HTMLTAG_307__1TAG_307__HT_3088___ ___HTMLTAG_309__HTMLTAG_310___2___HTMLTAG_311__HTMLTAG_312___最小權限___HTMLTAG_313__HTMLTAG_314___僅分配所需的最低角色__HTMLTAG_315__HTMLTAG_316___ ___HTMLTAG_317__HTMLTAG_318___3___HTMLTAG_319__HTMLTAG_320___輪替機密___HTMLTAG_321__HTMLTAG_322___定期更改client_secret____HTMLTAG_323__HTMLTAG_324___ ___HTMLTAG_325__HTMLTAG_326___4___HTMLTAG_327__HTMLTAG_328___令牌快取____HTMLTAG_329__HTMLTAG_330___在客戶端快取令牌,過期前刷新_____HTMLTAG_331__HTMLTAG_332_____HTMLTAG_331__HTMLTAG_332_____HTMLTAG_331__HTMLTAG_332_____HTMLTAG_331__HTMLTAG_332 ___HTMLTAG_333__HTMLTAG_334___5___HTMLTAG_335__HTMLTAG_336___單獨的客戶端___HTMLTAG_337__HTMLTAG_338___每個服務使用自己的客戶端,沒有共享憑證___ ___HTMLTAG_341__HTMLTAG_342___6___HTMLTAG_343__HTMLTAG_344___網路策略___HTMLTAG_345__HTMLTAG_346___限制服務之間的網路存取___HTMLTAG_347__HTMLTAG_348___ ___HTMLTAG_349__HTMLTAG_350___7___HTMLTAG_351__HTMLTAG_352___審核日誌記錄___HTMLTAG_353__HTMLTAG_354___記錄服務帳戶令牌請求___HTMLTAG_355__HTMLTAG_356___HTMLTAG_359__HTMLTAG_360___7.3 閘道速率限制___HTMLTAG_361__HTMLTAG_362
# Nginx rate limiting
http {
# Định nghĩa rate limit zones
# $binary_remote_addr: limit per IP
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
# Limit per authenticated user (từ JWT sub claim)
limit_req_zone $http_x_user_id zone=user_limit:10m rate=30r/s;
server {
# Apply rate limiting cho API endpoints
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_req zone=user_limit burst=50 nodelay;
limit_req_status 429;
# Custom error response cho rate limit
error_page 429 = @rate_limited;
# ... proxy_pass ...
}
location @rate_limited {
default_type application/json;
return 429 '{"error": "Too Many Requests", "message": "Rate limit exceeded. Please retry after a moment."}';
}
}
}
HTMLTAG_363__HTMLTAG_364___8。摘要___HTMLTAG_365__HTMLTAG_366
___HTMLTAG_369__HTMLTAG_370___網關____HTMLTAG_371__HTMLTAG_372___複雜性___HTMLTAG_373__HTMLTAG_374___效能____HTMLTAG_375__HTMLTAG_376____374___效能____HTMLTAG_375__HT__TAG_376___最適合___7HTTAGML____43____ ___HTMLTAG_381__HTMLTAG_382___Nginx + lua-resty-openidc___HTMLTAG_383__HTMLTAG_384___中____HTMLTAG_385__HTMLTAG_386___非常高___HTMLTAG_387__HTMLTAG_388___高流量,自訂邏輯___MLTAG_38998___ ___HTMLTAG_391__HTMLTAG_392___Nginx + OAuth2 代理___HTMLTAG_393__HTMLTAG_394___低___HTMLTAG_395__HTMLTAG_396___高___HTMLTAG_397__HTMLTAG_398___1設定 ___HTMLTAG_401__HTMLTAG_402___Kong___HTMLTAG_403__HTMLTAG_404___中___HTMLTAG_405__HTMLTAG_406___高___HTMLTAG_407__HTMLTAG_408___企業、406___72GMLTAG_407__HTMLTAG_408___」企業、外掛程式生態系統___MLGML_40910____4____ ___HTMLTAG_411__HTMLTAG_412___Traefik____HTMLTAG_413__HTMLTAG_414___低___HTMLTAG_415__HTMLTAG_416___高___HTMLTAG_417__HTMLTAG_418________HTMLTAG_423__HTMLTAG_424___API 閘道 + Keycloak 部署清單:HTMLTAG_425__HTMLTAG_426
___HTMLTAG_429__HTMLTAG_430___#___HTMLTAG_431__HTMLTAG_432___類別____HTMLTAG_433__HTMLTAG_434___狀態____HTMLTAG_435__HTMLTAG_436___ ___HTMLTAG_439__HTMLTAG_440___1___HTMLTAG_441__HTMLTAG_442___網關處的 JWT 驗證(JWKS 快取)___HTMLTAG_443__HTMLTAG_444______________________ ___HTMLTAG_447__HTMLTAG_448___2___HTMLTAG_449__HTMLTAG_450___將使用者標頭傳播到下游服務____HTMLTAG_451__HTMLTAG_452___________HTMLTAG_453__HTMLTAG_454___ ___HTMLTAG_455__HTMLTAG_456___3___HTMLTAG_457__HTMLTAG_458___用於內部通訊的服務帳戶___HTMLTAG_459__HTMLTAG_460_______________________HTMLTAG_461__HTMLTAG_462___ ___HTMLTAG_463__HTMLTAG_464___4___HTMLTAG_465__HTMLTAG_466___每個 IP 和每個使用者的速率限制____HTMLTAG_467__HTMLTAG_468_________________HTMLTAG_469__HTMLTAG_470___ ___HTMLTAG_471__HTMLTAG_472___5___HTMLTAG_473__HTMLTAG_474___網關處的 CORS 設定___HTMLTAG_475__HTMLTAG_476_______________________HTMLTAG_477__HTMLTAG_478___ ___HTMLTAG_479__HTMLTAG_480___6___HTMLTAG_481__HTMLTAG_482___運行狀況檢查端點(繞過驗證)___HTMLTAG_483__HTMLTAG_484___________HTMLTAG_485__HTMLTAG_486___ ___HTMLTAG_487__HTMLTAG_488___7___HTMLTAG_489__HTMLTAG_490___網關處的 TLS 終止___HTMLTAG_491__HTMLTAG_492________________HTMLTAG_493__HTMLTAG_491__HTMLTAG_492________________HTMLTAG_493__HTMLTAG_494___ ___HTMLTAG_495__HTMLTAG_496___8___HTMLTAG_497__HTMLTAG_498___記錄與監視___HTMLTAG_499__HTMLTAG_500_____________HTMLTAG_501__HTMLTAG_502___ ___HTMLTAG_503__HTMLTAG_504___9___HTMLTAG_505__HTMLTAG_506___客戶端秘密輪調策略___HTMLTAG_507__HTMLTAG_508____________HTMLTAG_509__HTMLTAG_510___ ___HTMLTAG_511__HTMLTAG_512___10____HTMLTAG_513__HTMLTAG_514___令牌過期與刷新處理___HTMLTAG_515__HTMLTAG_516___________HTMLTAG_517__HTMLTAG_518___下一個系列將深入探討 Keycloak 叢集、生產部署和效能調整等進階主題。