英文:
validate claims inside JWT using envoy
问题
{
"aud": "123123-1232-123123-2323-123",
"iss": "https://url",
"roles": ["default"]
}
我的JWT包含上述声明。我需要验证三个事项:
- 受众(aud):aud
- 发行者(iss):iss
- 角色(roles):'roles' 应该存在于JWT中,其值应该是一个包含 'default' 的数组。这可以通过Envoy实现如下:
我进行了一些研究,找到了一种验证受众 'aud' 和发行者 'iss' 的方法。
http_filters:
- name: envoy.filters.http.jwt_authn
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
providers:
"auth-iam":
issuer: https://url
forward: true
audiences:
- 123123-1232-123123-2323-123
remote_jwks:
http_uri:
uri: https://url/keys
cluster: auth-iam
timeout: 5s
cache_duration:
seconds: 900
rules:
- match:
prefix: /actuator/health
- match:
prefix: /
requires:
provider_name: auth-iam
英文:
{
"aud": "123123-1232-123123-2323-123",
"iss": "https://url",
"iat": 2112,
"nbf": 1212,
"exp": 1212,
"aio": "ewq32ee23e2e=",
"azp": "123123-1232-123123-2323-123",
"azpacr": "1",
"oid": "123123-1232-123123-2323-123",
"rh": "1.qqfn4wanflwf3aldAAA.",
"roles": [
"default"
],
"sub": "123123-1232-123123-2323-123"
}
My JWT contains the above claims. i have to validate 3 things
- audience : aud
- issuer : iss
- roles : 'roles' should be present in JWT. Its value array should contain 'default'. How can this be achieved with envoy?
I researched a bit and found a way to validate audience 'aud' and issuer 'iss'.
http_filters:
- name: envoy.filters.http.jwt_authn
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
providers:
"auth-iam":
issuer: https://url
forward: true,
audiences:
- 123123-1232-123123-2323-123 # [audience]
remote_jwks:
http_uri: # [3]
uri: https://url/keys # [simple]
cluster: auth-iam
timeout: 5s
cache_duration:
seconds: 900
rules:
- match:
prefix: /actuator/health
- match:
prefix: /
requires:
provider_name: auth-iam
答案1
得分: 1
我通过添加一个Lua过滤器并编写一个Lua脚本来验证令牌声明,实现了上述操作。它分为以下2个步骤:
- 将JWT的有效载荷添加到变量 jwt_payload。
- name: envoy.filters.http.jwt_authn
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
providers:
"auth-iam":
issuer: https://url,
forward: true
audiences:
- 123123-1232-123123-2323-123
remote_jwks:
http_uri:
uri: https://login.microsoftonline.com/common/discovery/v2.0/keys
cluster: auth-iam
timeout: 5s
cache_duration:
seconds: 900
payload_in_metadata: jwt_payload
rules:
- match:
prefix: /health
- match:
prefix: /
requires:
provider_name: auth-iam
- 检索有效载荷并编写自定义逻辑来验证令牌声明。该过滤器应添加在
- name: envoy.filters.http.router
的上方。
- name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
function envoy_on_request(request_handle)
local meta = request_handle:streamInfo():dynamicMetadata()
for key, value in pairs(meta) do
if (value.jwt_payload.roles == nil or value.jwt_payload.roles[1] ~= "default") then
request_handle:respond({[":status"] = "403",}, "JWT验证失败。")
end
end
end
英文:
i was able to acheive the above by adddding a lua filter and writing a lua script to validate token claims. it works in these 2 steps :
-
add the payload from JWT to a variable jwt_payload.
- name: envoy.filters.http.jwt_authn typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication providers: "auth-iam": issuer: https://url, forward: true audiences: - 123123-1232-123123-2323-123 remote_jwks: http_uri: uri: https://login.microsoftonline.com/common/discovery/v2.0/keys cluster: auth-iam timeout: 5s cache_duration: seconds: 900 payload_in_metadata: jwt_payload rules: - match: prefix: /health - match: prefix: / requires: provider_name: auth-iam
-
retreive the payload and write custom logic to validate the token claims. the filter would be added just above
- name: envoy.filters.http.router
- name: envoy.filters.http.lua typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua inline_code: | function envoy_on_request(request_handle) local meta = request_handle:streamInfo():dynamicMetadata() for key, value in pairs(meta) do -- request_handle:logInfo("extract dynamicMetadata key: "..key) -- request_handle:logInfo("extract dynamicMetadata value: "..value.jwt_payload.roles[1]) if(value.jwt_payload.roles == nil or value.jwt_payload.roles[1] ~= "default") then request_handle:respond({[":status"] = "403",},"JWT validation failed.") end end end
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论