Enrutamiento basado en claims JWT
Esta tarea muestra cómo enrutar solicitudes basadas en claims JWT en un ingress gateway de Istio utilizando la autenticación de solicitudes y el virtual service.
Nota: esta feature solo admite ingress gateway de Istio y requiere el uso tanto de la autenticación de solicitudes como del virtual service para validar y enrutar correctamente basándose en los claims JWT.
Antes de empezar
Comprenda la política de autenticación de Istio y los conceptos de virtual service.
Instale Istio utilizando la guía de instalación de Istio.
Despliegue un workload,
httpbin
en un namespace, por ejemplofoo
, y expóngalo a través del ingress gateway de Istio con este comando:$ kubectl create ns foo $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n foo $ kubectl apply -f @samples/httpbin/httpbin-gateway.yaml@ -n foo
Siga las instrucciones en Determinación de la IP y los puertos de ingress para definir las variables de entorno
INGRESS_HOST
eINGRESS_PORT
.Verifique que el workload
httpbin
y el ingress gateway funcionan como se espera utilizando este comando:$ curl "$INGRESS_HOST:$INGRESS_PORT"/headers -s -o /dev/null -w "%{\http_code}\n" 200
Configuración del enrutamiento de entrada basado en claims JWT
El ingress gateway de Istio admite el enrutamiento basado en JWT autenticados, lo que es útil para el enrutamiento basado en la identidad del usuario final y más seguro en comparación con el uso de atributos HTTP no autenticados (por ejemplo, ruta o cabecera).
Para enrutar basándose en claims JWT, primero cree la autenticación de solicitudes para habilitar la validación de JWT:
$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: RequestAuthentication metadata: name: ingress-jwt namespace: istio-system spec: selector: matchLabels: istio: ingressgateway jwtRules: - issuer: "testing@secure.istio.io" jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.26/security/tools/jwt/samples/jwks.json" EOF
La autenticación de solicitudes habilita la validación de JWT en el ingress gateway de Istio para que los claims JWT validados puedan usarse posteriormente en el virtual service para fines de enrutamiento.
La autenticación de solicitudes se aplica en el ingress gateway porque el enrutamiento basado en claims JWT solo es compatible en los ingress gateways.
Nota: la autenticación de solicitudes solo verificará el JWT si existe en la solicitud. Para que el JWT sea obligatorio y rechace la solicitud si no incluye JWT, aplique la política de autorización como se especifica en la tarea.
Actualice el virtual service para enrutar basándose en claims JWT validados:
$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: httpbin namespace: foo spec: hosts: - "*" gateways: - httpbin-gateway http: - match: - uri: prefix: /headers headers: "@request.auth.claims.groups": exact: group1 route: - destination: port: number: 8000 host: httpbin EOF
El virtual service utiliza la cabecera reservada “@request.auth.claims.groups” para coincidir con el claim JWT
groups
. El prefijo@
denota que coincide con los metadatos derivados de la validación de JWT y no con las cabeceras HTTP.Se admiten claims de tipo cadena, lista de cadenas y claims anidados. Utilice
.
o[]
como separador para claims anidados nombres. Por ejemplo, “@request.auth.claims.name.givenName” o “@request.auth.claims[name][givenName]” coinciden con los claims anidadosname
ygivenName
, son equivalentes aquí. Cuando el nombre del claim contiene.
, solo se puede usar[]
como separador.
Validación del enrutamiento de entrada basado en claims JWT
Valide que el ingress gateway devuelve el código HTTP 404 sin JWT:
$ curl -s -I "http://$INGRESS_HOST:$INGRESS_PORT/headers" HTTP/1.1 404 Not Found ...
También puede crear la política de autorización para rechazar explícitamente la solicitud con el código HTTP 403 cuando falta el JWT.
Valide que el ingress gateway devuelve el código HTTP 401 con un JWT inválido:
$ curl -s -I "http://$INGRESS_HOST:$INGRESS_PORT/headers" -H "Authorization: Bearer some.invalid.token" HTTP/1.1 401 Unauthorized ...
El 401 es devuelto por la autenticación de solicitudes porque el JWT falló la validación.
Valide que el ingress gateway enruta la solicitud con un token JWT válido que incluye el claim
groups: group1
:$ TOKEN_GROUP=$(curl https://raw.githubusercontent.com/istio/istio/release-1.26/security/tools/jwt/samples/groups-scope.jwt -s) && echo "$TOKEN_GROUP" | cut -d '.' -f2 - | base64 --decode {"exp":3537391104,"groups":["group1","group2"],"iat":1537391104,"iss":"testing@secure.istio.io","scope":["scope1","scope2"],"sub":"testing@secure.istio.io"}
$ curl -s -I "http://$INGRESS_HOST:$INGRESS_PORT/headers" -H "Authorization: Bearer $TOKEN_GROUP" HTTP/1.1 200 OK ...
Valide que el ingress gateway devuelve el código HTTP 404 con un JWT válido pero que no incluye el claim
groups: group1
:$ TOKEN_NO_GROUP=$(curl https://raw.githubusercontent.com/istio/istio/release-1.26/security/tools/jwt/samples/demo.jwt -s) && echo "$TOKEN_NO_GROUP" | cut -d '.' -f2 - | base64 --decode {"exp":4685989700,"foo":"bar","iat":1532389700,"iss":"testing@secure.istio.io","sub":"testing@secure.istio.io"}
$ curl -s -I "http://$INGRESS_HOST:$INGRESS_PORT/headers" -H "Authorization: Bearer $TOKEN_NO_GROUP" HTTP/1.1 404 Not Found ...
Limpieza
Elimine el namespace
foo
:$ kubectl delete namespace foo
Elimine la autenticación de solicitudes:
$ kubectl delete requestauthentication ingress-jwt -n istio-system