Copy JWT Claims to HTTP Headers
This task shows you how to copy valid JWT claims to HTTP headers after JWT authentication is successfully completed via an Istio request authentication policy.
Before you begin
Before you begin this task, do the following:
Familiarize yourself with Istio end user authentication support.
Install Istio using Istio installation guide.
Deploy
httpbin
andsleep
workloads in namespacefoo
with sidecar injection enabled. Deploy the example namespace and workloads using these commands:$ kubectl create ns foo $ kubectl label namespace foo istio-injection=enabled $ kubectl apply -f @samples/httpbin/httpbin.yaml@ -n foo $ kubectl apply -f @samples/sleep/sleep.yaml@ -n foo
Verify that
sleep
successfully communicates withhttpbin
using this command:$ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/ip -sS -o /dev/null -w "%{http_code}\n" 200
Allow requests with valid JWT and list-typed claims
The following command creates the
jwt-example
request authentication policy for thehttpbin
workload in thefoo
namespace. This policy accepts a JWT issued bytesting@secure.istio.io
and copies the value of claimfoo
to an HTTP headerX-Jwt-Claim-Foo
:$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: "jwt-example" namespace: foo spec: selector: matchLabels: app: httpbin jwtRules: - issuer: "testing@secure.istio.io" jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.21/security/tools/jwt/samples/jwks.json" outputClaimToHeaders: - header: "x-jwt-claim-foo" claim: "foo" EOF
Verify that a request with an invalid JWT is denied:
$ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -H "Authorization: Bearer invalidToken" -w "%{http_code}\n" 401
Get the JWT which is issued by
testing@secure.istio.io
and has a claim with keyfoo
.$ TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.21/security/tools/jwt/samples/demo.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode - {"exp":4685989700,"foo":"bar","iat":1532389700,"iss":"testing@secure.istio.io","sub":"testing@secure.istio.io"}
Verify that a request with a valid JWT is allowed:
$ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -H "Authorization: Bearer $TOKEN" -w "%{http_code}\n" 200
Verify that a request contains a valid HTTP header with JWT claim value:
$ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -sS -H "Authorization: Bearer $TOKEN" | grep "X-Jwt-Claim-Foo" | sed -e 's/^[ \t]*//' "X-Jwt-Claim-Foo": "bar"
Clean up
Remove the namespace foo
:
$ kubectl delete namespace foo