Getting a "required audience is missing" when trying to access my Spring backend deployed on a K8s/Argocd server

Viewed 3216

I have a Java Spring backend that I've deployed onto ArgoCD with Kubernetes manifests. The backend is protected by having the user login into Keycloak. After it is deployed, I go to /api/application-info, and it then makes me log in to Keycloak. But after it I log in, it redirects me back and I just see This page isn’t working. If the problem continues, contact the site owner. HTTP ERROR 401.

Looking at the backend logs, I see Bearer error="invalid_token", error_description="An error occurred while attempting to decode the Jwt: The required audience is missing", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1". After googling, one page said that perhaps the client ID was wrong, but I double checked it and it was fine. I am setting the Keycloak client ID in the "application.yml" file, for example:

spring:
  security:
    oauth2:
      client:
        provider:
          oidc:
            issuer-uri: https://mykeycloak.com/auth/realms/myrealm
        registration:
          oidc:
            client-id: myclientid
            client-secret: myclientpw

Anyone know how else I can debug this?

Here is the Virtual Service. I know it is working because (1) I can go to /api and it will bring me to /api/, and (2) I go to /api/application-info, and it then makes me log in to Keycloak.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ingress
spec:
  hosts:
    - myhost.io
  gateways:
    - public-gateway.istio-system.svc.cluster.local
  http:
    - match:
        - uri:
            exact: /api
      redirect:
        uri: /api/
    - match:
        - uri:
            prefix: /api/
      rewrite:
        uri: /api/
      route:
        - destination:
            host: mysite-be
            port:
              number: 80
      websocketUpgrade: true
    - match:
        - uri:
            prefix: /
      route:
        - destination:
            host: mysite-fe
            port:
              number: 80
2 Answers

JWT tokens can have an optional "aud" property which indicates the intended audience of the token. The audience in your scenario is your Spring boot application, which means the token should be issued in regards to accessing your Spring boot application.

As part of the validation of the JWT token on your Spring boot application, if the "aud" property exists, its value will also gets checked to ensure the token is issued to be used by the application.

I guess the token generated for your login, doesn't contain proper/expected value for "aud" property. In such cases, you would probably need to configure your client on Keycloak.

You can see the properties in your token by pasting it at https://jwt.io/ and inspect the "aud" property.

A workaround to fix this could also be to disable the audience validation completely in your application. You can do this by adding the following property to your keycloak.json file:

{
    ...
    verify-token-audience: false
}

The actual solution should be to investigate the way it's being generated and make it produce proper value. I recommend to check Audience Support in Keycloak documentation, explaining how they're being generated and can be configured in Keycloak.

Based on RFC-7519 JSON Web Token spec:

The "aud" (audience) claim identifies the recipients that the JWT is intended for. Each principal intended to process the JWT MUST identify itself with a value in the audience claim. If the principal processing the claim does not identify itself with a value in the "aud" claim when this claim is present, then the JWT MUST be rejected. In the general case, the "aud" value is an array of case- sensitive strings, each containing a StringOrURI value. In the special case when the JWT has one audience, the "aud" value MAY be a single case-sensitive string containing a StringOrURI value. The interpretation of audience values is generally application specific. Use of this claim is OPTIONAL.

Based on the error you're describing, it may be that your cluster has additional authorization configurations being injected. You probably want to check those and make sure you're not getting extra/unexpected configurations that aren't being handled.

Related