<p>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 <code>This page isn’t working. If the problem continues, contact the site owner. HTTP ERROR 401</code>.</p>
<p>Looking at the backend logs, I see <code>Bearer error=&quot;invalid_token&quot;, error_description=&quot;An error occurred while attempting to decode the Jwt: The required audience is missing&quot;, error_uri=&quot;https://tools.ietf.org/html/rfc6750#section-3.1&quot;</code>. 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 &quot;application.yml&quot; file, for example:</p>
<pre><code>spring:
  security:
    oauth2:
      client:
        provider:
          oidc:
            issuer-uri: https://mykeycloak.com/auth/realms/myrealm
        registration:
          oidc:
            client-id: myclientid
            client-secret: myclientpw
</code></pre>
<p>Anyone know how else I can debug this?</p>
<p>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.</p>
<pre><code>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
</code></pre>

<p>JWT tokens can have an optional &quot;aud&quot; 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.</p>
<p>As part of the validation of the JWT token on your Spring boot application, if the &quot;aud&quot; property exists, its value will also gets checked to ensure the token is issued to be used by the application.</p>
<p>I guess the token generated for your login, doesn't contain proper/expected value for &quot;aud&quot; property. In such cases, you would probably need to configure your client on Keycloak.</p>
<p>You can see the properties in your token by pasting it at <a href="https://jwt.io/" rel="nofollow noreferrer">https://jwt.io/</a> and inspect the &quot;<strong>aud</strong>&quot; property.</p>
<p><strong>A workaround</strong> 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 <code>keycloak.json</code> file:</p>
<pre><code>{
    ...
    verify-token-audience: false
}
</code></pre>
<p><strong>The actual solution</strong> should be to investigate the way it's being generated and make it produce proper value. I recommend to check <a href="https://www.keycloak.org/docs/latest/server_admin/#_audience" rel="nofollow noreferrer">Audience Support</a> in Keycloak documentation, explaining how they're being generated and can be configured in Keycloak.</p>
<p>Based on <a href="https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3" rel="nofollow noreferrer">RFC-7519 JSON Web Token</a> spec:</p>
<blockquote>
<p>The &quot;aud&quot; (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
&quot;aud&quot; claim when this claim is present, then the JWT MUST be
rejected.  In the general case, the &quot;aud&quot; value is an array of case-
sensitive strings, each containing a StringOrURI value.  In the
special case when the JWT has one audience, the &quot;aud&quot; 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.</p>
</blockquote>
