Маршрутизація на основі вимог JWT
Це завдання показує, як маршрутизувати запити на основі заявок JWT на шлюзі входу Istio, використовуючи автентифікацію запитів та віртуальні сервіси.
Зверніть увагу: ця функція підтримується тільки для шлюзу входу Istio і вимагає використання як автентифікації запитів, так і віртуального сервісу для належної перевірки та маршрутизації на основі заявок JWT.
Перед початком
Ознайомтеся з концепціями політики автентифікації Istio та віртуального сервісу.
Встановіть Istio, дотримуючись посібника з установки Istio.
Розгорніть навантаження, наприклад,
httpbin
в просторі імен, наприкладfoo
, та експонуйте його через шлюз входу Istio за допомогою цієї команди:$ 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
Слідуйте інструкціям у розділі Визначення IP та портів входу для визначення змінних середовища
INGRESS_HOST
таINGRESS_PORT
.Перевірте, що навантаження
httpbin
та шлюз входу працюють як очікується, використовуючи цю команду:$ curl "$INGRESS_HOST:$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n" 200
Налаштування маршрутизації ingress на основі заявок JWT
Istio ingress gateway підтримує маршрутизацію на основі автентифікованого JWT, що є корисним для маршрутизації на основі ідентичності кінцевого користувача і є більш безпечним у порівнянні з використанням неавтентифікованих HTTP атрибутів (наприклад, шлях або заголовок).
Для маршрутизації на основі заявок JWT спочатку створіть автентифікацію запитів для ввімкнення перевірки 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.24/security/tools/jwt/samples/jwks.json" EOF
Автентифікація запиту уможливлює перевірку JWT на вхідному шлюзі Istio, щоб підтверджені JWT-запити пізніше можуть бути використані у віртуальному сервісі для маршрутизації.
Автентифікація запиту застосовується на вхідному шлюзі, оскільки маршрутизація на основі заявок JWT підтримується тільки на вхідних шлюзах.
Примітка: автентифікація запитів перевірятиме JWT лише в разі його наявності у запиті. Щоб зробити JWT обовʼязковим і відхиляти запити, які не містять JWT, застосуйте політику авторизації, як зазначено в завданні.
Оновіть віртуальну службу, щоб прокласти маршрут на основі підтверджених заявок JWT:
$ 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
Віртуальний сервіс використовує зарезервований заголовок
"@request.auth.claims.groups"
для збігів з заявкою JWTgroups
. Префікс@
позначає, що він має збіг з метаданими, отриманими з перевірки JWT, а не з HTTP заголовками.Підтримуються заявки типу рядок, список рядків і вкладені заявки. Використовуйте
.
або[]
як роздільник для імен вкладених заявок. Наприклад,"@request.auth.claims.name.givenName"
або"@request.auth.claims[name][givenName]"
збігається з вкладеними заявкамиname
таgivenName
, вони еквівалентні тут. Коли імʼя заявки містить.
, лише[]
може бути використано як роздільник.
Перевірка маршрутизації вхідних даних на основі заявок JWT
Перевірка вхідного шлюзу повертає HTTP код 404 без JWT:
$ curl -s -I "http://$INGRESS_HOST:$INGRESS_PORT/headers" HTTP/1.1 404 Not Found ...
Ви також можете створити політику авторизації для явного відхилення запиту з HTTP-кодом 403, коли JWT відсутній.
Перевірка вхідного шлюзу повертає HTTP код 401 з недійсним JWT:
$ curl -s -I "http://$INGRESS_HOST:$INGRESS_PORT/headers" -H "Authorization: Bearer some.invalid.token" HTTP/1.1 401 Unauthorized ...
401 повертається при перевірці автентичності запиту, оскільки JWT не пройшов перевірку.
Переконайтеся, що вхідний шлюз направляє запит з дійсним токеном JWT, який містить заявку
groups: group1
:$ TOKEN_GROUP=$(curl https://raw.githubusercontent.com/istio/istio/release-1.24/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 ...
Перевірте вхідний шлюз, і він поверне HTTP код 404 з дійсним JWT, але не містить твердження
groups: group1
:$ TOKEN_NO_GROUP=$(curl https://raw.githubusercontent.com/istio/istio/release-1.24/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 ...
Очищення
Видаліть простір імен
foo
:$ kubectl delete namespace foo
Видаліть автентифікацію запиту:
$ kubectl delete requestauthentication ingress-jwt -n istio-system