使用JWT认证授权
应用服务网格中使用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