应用服务网格

使用JWT认证授权

2025-08-14 02:41:24

服务网格中使用JWT实现对请求的身份认证,进一步可以配置授权策略,限制对请求的授权。

 

首先部署测试应用

参考以上示例部署sleep和httpbin应用,pod列表如下:


配置JWT认证策略:

apiVersion: security.istio.io/v1beta1

kind: RequestAuthentication

metadata:

  name: "jwt-example"

  namespace: bookinfo

spec:

  selector:

    matchLabels:

      app: httpbin

  jwtRules:

  - issuer: "testing@secure.istio.io"

jwks: '{ "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-envvQ","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65pHymX-P7KfIupjf59vsdo91bSP9C8H07pSAGQO1MV_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5DXIg_pbhLdKXbi66GlVeK6ABZOUW3WYtnNHD-91gVuoeJT_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoUqgBo_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZbDAa_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqTZ0BJ_EyxOGuHJrLsn00fnMQ"}]}'

 

使用非法的JWT访问,可以看到返回了401错误:

kubectl exec "$(kubectl get pod -l app=sleep -n bookinfo -o jsonpath={.items..metadata.name})" -c sleep -n bookinfo -- curl "http://httpbin:8000/headers" -sS -o /dev/null -H "Authorization: Bearer invalidToken" -w "%{http_code}\n"

401

 

不带JWT头部时会放过请求(返回200):

kubectl exec "$(kubectl get pod -l app=sleep -n bookinfo -o jsonpath={.items..metadata.name})" -c sleep -n bookinfo -- curl "http://httpbin:8000/headers" -sS -o /dev/null -w "%{http_code}\n"

200

 

创建授权策略,要求请求带有合法的JWT才允许访问:

apiVersion: security.istio.io/v1beta1

kind: AuthorizationPolicy

metadata:

  name: require-jwt

  namespace: bookinfo

spec:

  selector:

    matchLabels:

      app: httpbin

  action: ALLOW

  rules:

  - from:

    - source:

       requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]

再次不带JWT访问返回了403

kubectl exec "$(kubectl get pod -l app=sleep -n bookinfo -o jsonpath={.items..metadata.name})" -c sleep -n bookinfo -- curl "http://httpbin:8000/headers" -sS -o /dev/null -w "%{http_code}\n"

403

 

使用已经生成好的token验证访问,可以看到返回了200状态码:

TOKEN= eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg

kubectl exec "$(kubectl get pod -l app=sleep -n bookinfo -o jsonpath={.items..metadata.name})" -c sleep -n bookinfo -- curl "http://httpbin:8000/headers"  -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n"

200

 

修改授权策略,只允许JWT信息中groups字段包含group1的时候才允许访问,策略如下:

apiVersion: security.istio.io/v1beta1

kind: AuthorizationPolicy

metadata:

  name: require-jwt

  namespace: bookinfo

spec:

  selector:

    matchLabels:

      app: httpbin

  action: ALLOW

  rules:

  - from:

    - source:

       requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]

    when:

    - key: request.auth.claims[groups]

      values: ["group1"]

使用上述TOKEN访问返回403

kubectl exec "$(kubectl get pod -l app=sleep -n bookinfo -o jsonpath={.items..metadata.name})" -c sleep -n bookinfo -- curl "http://httpbin:8000/headers"  -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n"

403

 

更新TOKEN

TOKEN= eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjM1MzczOTExMDQsImdyb3VwcyI6WyJncm91cDEiLCJncm91cDIiXSwiaWF0IjoxNTM3MzkxMTA0LCJpc3MiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyIsInNjb3BlIjpbInNjb3BlMSIsInNjb3BlMiJdLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.EdJnEZSH6X8hcyEii7c8H5lnhgjB5dwo07M5oheC8Xz8mOllyg--AHCFWHybM48reunF--oGaG6IXVngCEpVF0_P5DwsUoBgpPmK1JOaKN6_pe9sh0ZwTtdgK_RP01PuI7kUdbOTlkuUi2AO-qUyOm7Art2POzo36DLQlUXv8Ad7NBOqfQaKjE9ndaPWT7aexUsBHxmgiGbz1SyLH879f7uHYPbPKlpHU6P9S-DaKnGLaEchnoKnov7ajhrEhGXAQRukhDPKUHO9L30oPIr5IJllEQfHYtt6IZvlNUGeLUcif3wpry1R5tBXRicx2sXMQ7LyuDremDbcNy_iE76Upg

再次访问返回200

kubectl exec "$(kubectl get pod -l app=sleep -n bookinfo -o jsonpath={.items..metadata.name})" -c sleep -n bookinfo -- curl "http://httpbin:8000/headers"  -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n"

200


cOjOr05Cpgu6