如何提取特使中的jwt



如何提取特使中的jwt将提取的值放入标头

我需要在http_filters下面添加一些额外的属性,但我对此一无所知,我已经研究了特使文档中的jwtProviderjwtHeader

这是我的特使。yaml文件这个配置有什么问题:

admin: 
access_log_path: "/dev/null"
address: 
socket_address:
address: 0.0.0.0
port_value: 8001
static_resources:
listeners:
- name: main
address:
socket_address:
address: 0.0.0.0
port_value: 1337
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/"
route:
host_rewrite_literal: 0.0.0.0
cluster: web_service
http_filters:
- name: config.filter.http.jwt_authn.v2alpha.JwtHeader
from_params:
- jwt_token
- 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.usr)
end
end
- name: envoy.filters.http.router
clusters:
- name: web_service
connect_timeout: 5s
type: STRICT_DNS  # static
load_assignment:
cluster_name: web_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 0.0.0.0
port_value: 3000`enter code here`

如果我理解正确,你想要:

  1. 特使从Authorization报头(Authorization: Bearer ...(中提取并验证JWT
  2. 如果JWT得到验证,特使会将请求转发到您的集群
  3. 在该转发请求中,特使添加一个或多个与解码的JWT有效载荷项相对应的标头

您可以通过更改配置的http_filters部分来执行此操作。我使用的是特使v1.21.0。为了方便起见,我在这里使用了本地JWKS配置(HS256算法,在base64中秘密helloworld=aGVsbG93b3JsZA==(。但请注意,您也可以定义一个远程JWKS配置。

http_filters:
- name: envoy.filters.http.jwt_authn
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication"
providers:
jwt_auth:
local_jwks:
inline_string: '{"keys":[{"typ": "JWT", "kty":"oct","alg":"HS256","kid":"df","k":"aGVsbG93b3JsZA=="}]}'
from_headers:
- name: Authorization
value_prefix: "Bearer "
payload_in_metadata: jwt_payload
rules:
- match:
prefix: "/"
requires:
provider_name: jwt_auth
- 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:headers():add("jwt-extracted-user", value.jwt_payload.usr)
end
end
- name: envoy.filters.http.router

第一滤波器(envoy.filters.http.jwt_authn(

第一滤波器(envoy.filters.http.jwt_authn(被配置为:

  • 使用一些本地JWKS配置:请参阅local_jwks.inline_string
  • Authorization头中获取JWT(在Bearer部分之后(:参见from_headers属性
  • 将经过验证的JWT有效载荷写入值为jwt_payloadStreamInfoDynamicMetadata:参见payload_in_metadata
  • 定义一些规则,将匹配与上面定义的提供程序(jwt_auth(链接起来:请参阅rules

第二滤波器(envoy.filters.http.lua(

一旦配置了第一个过滤器,现在就可以处理StreamInfoDynamicMetadata来添加新的标头。这是由第二滤波器(envoy.filters.http.lua(完成的。内联代码:

function envoy_on_request(request_handle)
local meta = request_handle:streamInfo():dynamicMetadata()
for key, value in pairs(meta) do
request_handle:headers():add("jwt-extracted-user", value.jwt_payload.usr)
end
end
  • StreamInfoDynamicMetadata上迭代
  • 从JWT有效载荷中提取usr字段(命名为jwt_payload,如在第一个过滤器的payload_in_metadata属性中配置的(
  • 将该信息(value.jwt_payload.usr(添加到名为jwt-extracted-user的新标头中

测试

随着我的答案http_filters在您的配置中取代了您的答案,您可以启动一个特使来执行您想要的操作,并使用包含以下有效载荷的有效JWT进行测试:

{
"usr": "John Doe"
}

刚刚运行:

curl 
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJKb2huIERvZSJ9.-9p297JIIXkHomuuvAFD7pghEtDhdKKAe8V0SqeDqU4' 
http://localhost:1337

JWT由特使验证,并通过名为jwt-extracted-user的新标头转发给您的web_service。为了证明这一点,我为您的web_service使用了一个简单的FlaskPython应用程序,只打印标题:

import sys
from flask import Flask
from flask import request
app = Flask(__name__)
@app.route("/")
def hello_world():
print(request.headers, file=sys.stderr)
return "Hello, world!"

if __name__ == '__main__':
app.run(host='0.0.0.0')

在Python应用程序的日志中,您应该看到以下内容:

Host: localhost:1337
User-Agent: curl/7.81.0
Accept: */*
X-Forwarded-Proto: http
X-Request-Id: 3a45f721-ccdd-4225-91ab-8ff4307c97de
Jwt-Extracted-User: John Doe
X-Envoy-Expected-Rq-Timeout-Ms: 15000

注意Jwt-Extracted-User的存在,它包含JWT有效载荷的usr字段。

学分

https://github.com/envoyproxy/envoy/issues/9716#issuecomment-577261856

扩展norbjd的答案,从envoyproxy v1.25.0版本开始,有一种方法可以将经过验证的JWT声明复制到HTTP请求标头。这是医生。

下面是我正在使用的配置中的片段。此配置将把sub声明从JWT令牌复制到x-jwt-claim-sub请求标头。

- name: envoy.filters.http.jwt_authn
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
providers:
my-idp:
forward: true
issuer: https://auth.my-idp.com/oauth2/rfthdw56433d
claim_to_headers:
- header_name: x-jwt-claim-sub
claim_name: sub
audiences:
- api://myapi
...
...                 

最新更新