Authentication and Authorization with JWT get 403

Hello,

I have installed on my cluster Kubernetes, hosted on DigitalOcean and with a lot of microcervices already deployed, the latest Istio release.

I have installed Istio with Helm with this options:

helm template install/kubernetes/helm/istio --namespace=istio-system --set gateways.istio-ingressgateway.sds.enabled=true --set global.k8sIngress.enabled=true --set global.k8sIngress.enableHttps=true --set global.k8sIngress.gatewayName=ingressgateway --set certmanager.enabled=true --set certmanager.email=<my-email> kubectl apply -f -

I modified the GW to use sds:
kubectl -n istio-system \ patch gateway istio-autogenerated-k8s-ingress --type=json \ -p='[{"op": "replace", "path": "/spec/servers/1/tls", "value": {"credentialName": "ingress-cert", "mode": "SIMPLE", "privateKey": "sds", "serverCertificate": "sds"}}]'

After that I have deployed a very simple APP(http-test) and I have configured the VirtualService.

So If I do a ‘curl http://IP-GW/test

I get 200 OK

Now, because in my infrastructure I already have a Keycloak configured, I would like to activate authentication and authorization on Istio.

I have the default GW “istio-autogenerated-k8s-ingress”

I configured the following policy:

kind: "Policy"
metadata:
  name: "gateway-jwt-policy"
  namespace: "istio-system"
spec:
  targets:
  - name: istio-ingressgateway
  origins:
  - jwt:
      issuer: "Keycloak-URI"
      jwksUri: "Keycloak-URI"
      audiences:
      - "client-test"
    incipalBinding: USE_ORIGIN

After that If make “curl http://IP-GW/test
I got 401 Unauthorized.

So I retrieve a JWT
TOKEN=curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=password&username=test&password=test&client_id=client-test&client_secret=<secret>&scope=openid" <keycloak>| jq -r '.access_token'

So If I do "curl -H "Authorization: Bearer $TOKEN
I get 200 OK

So the Authentication works fine.

After that I have activated the RBAC:

kind: ClusterRbacConfig
metadata:
  name: default
spec:
  mode: 'ON_WITH_INCLUSION'
  inclusion:
    services: ["http-test.istio-system.svc.cluster.local"]

So If I do 'curl -H “Authorization: Bearer $TOKEN” http://IP-GW/test

I get 403 Forbidden(RBAC: access denied)

this of course it’s expected

So I have configured a ServiceRole and a ServiceRoleBinding:

kind: ServiceRole
metadata:
  name: http-admin
  namespace: istio-system
spec:
  rules:
  - services: ["http-test.istio-system.svc.cluster.local"]
    methods: ["*"]
    paths: ["*"]


kind: ServiceRoleBinding
metadata:
  name: bind-http-admin
  namespace: istio-system
spec:
  subjects:
  - properties:
      request.auth.claims[x_role]: "operator"
  roleRef:
    kind: ServiceRole
    name: "http-admin"

The JWT provided by Keycloak is like:

HEADER:
{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "9fPzbbb3-E1r411Uj1Tuxrc1jutq4N7Vs1dt7sCKOvY"
}

PAYLOAD:
{
  "jti": "be075fff-ed7f-4387-abc7-a632c884a269",
  "exp": 1573227250,
  "nbf": 0,
  "iat": 1573226950,
  "iss": "keycloak",
  "aud": [
    "client-test",
    "account"
  ],
  "sub": "8388d162-7222-4d8d-bc5b-d68e2ab2c8ce",
  "typ": "Bearer",
  "azp": "client-test",
  "auth_time": 0,
  "session_state": "7c14902d-c0e9-4942-bd51-df45c2e222a8",
  "acr": "1",
  "allowed-origins": [
    ""
  ],
  "realm_access": {
    "roles": [
      "operator"
    ]
  },
  "resource_access": {
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "scope": "openid profile email",
  "email_verified": true,
  "x_role": "operator",
  "groups": [
    "operator"
  ],
  "preferred_username": "test",
  "email": "test@test.com",
  "userRoleName": [
    "operator"
  ]
}

So If I do ‘curl -H “Authorization: Bearer $TOKEN” http://IP-GW/test

I get always “403 Forbidden(RBAC: access denied)”

I don’t understand where is the issue!
I tried to activate mTLS, but the result is always the same.

Could you help me?

@YangminZhu please take a look, thanks.

@UNix3
It’s probably because you don’t have authentication policy on http-test.istio-system.svc.cluster.local so that the JWT token is not authenticated on the http-test service.

Could you add http-test to the target of the gateway-jwt-policy policy and try again?

Note, the ClusterRbacConfig, ServiceRole and ServiceRoleBinding are deprecated in favor of the new AuthorizationPolicy in 1.4: https://istio.io/blog/2019/v1beta1-authorization-policy/

@YangminZhu
Thanks for your suggestion I have added the target http-test in gateway-jwt-policy and now it works.