How to debug authentication with OIDC in Ververica Platform

Question

I am trying to setup OIDC based authentication & authorization in Ververica Platform. But it is not working as expected. How can I debug it?

Answer

Note: This section applies to Ververica Platform 2.0 - 2.8 Enterprise Edition.

Setting up authentication & authorization with OIDC in Ververica Platform can be done by following this documentation. In case there are problems, there are two ways to debug: one is to enable security-related debug logs via an environment variable, the other is to use this OIDC debugger from Nate Barbettini.

Enable Security-Related DEBUG logs

Create a Values file containing the following environment variable:

env:
  - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_SECURITY
    value: DEBUG

Upgrade Ververica Platform:

helm upgrade [-n namespace] vvp ververica/ververica-platform \
    --version <version> \
    --values <your original values files> \
    --values <the values file above>

Once Ververica Platform pods restarted, check the logs of the gateway container:

kubectl logs [-n namespace] <ververica-platform-pod> -c gateway

The following are simplified example logs of a successful authentication against Azure Active Directory. Depending on your OIDC provider, your logs may look different:

2021-07-20 07:24:34.292 DEBUG 1 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : Securing GET /login/oauth2/code/vvp?code=...&state=...&session_state=91654193-be67-4f51-a63f-97e18ffbe787
2021-07-20 07:24:34.292 DEBUG 1 --- [nio-8080-exec-5] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2021-07-20 07:24:34.612 DEBUG 1 --- [nio-8080-exec-5] .s.ChangeSessionIdAuthenticationStrategy : Changed session id from 6C0BC541C3A25A925B0B507884937F99
2021-07-20 07:24:34.612 DEBUG 1 --- [nio-8080-exec-5] .s.o.c.w.OAuth2LoginAuthenticationFilter : Set SecurityContextHolder to OAuth2AuthenticationToken [Principal=Name: [...], Granted Authorities: [[ROLE_USER, SCOPE_email, SCOPE_openid, SCOPE_profile]], User Attributes: [{sub=..., ver=2.0, aio=..., iss=..., groups=["...", ...], oid=..., preferred_username=jun@..., uti=..., nonce=..., tid=..., aud=..., nbf=Tue Jul 20 07:19:34 UTC 2021, rh=..., name=Jun Qin, exp=2021-07-20T08:24:34Z, iat=2021-07-20T07:19:34Z}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=...], Granted Authorities=...]
2021-07-20 07:24:34.612 DEBUG 1 --- [nio-8080-exec-5] o.s.s.web.DefaultRedirectStrategy        : Redirecting to http://localhost:8080/
2021-07-20 07:24:34.613 DEBUG 1 --- [nio-8080-exec-5] w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=OAuth2AuthenticationToken [...]] to HttpSession [org.apache.catalina.session.StandardSessionFacade@2b2cdb6c]
2021-07-20 07:24:34.613 DEBUG 1 --- [nio-8080-exec-5] w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=OAuth2AuthenticationToken [...]] to HttpSession [org.apache.catalina.session.StandardSessionFacade@2b2cdb6c]
2021-07-20 07:24:34.613 DEBUG 1 --- [nio-8080-exec-5] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
2021-07-20 07:24:34.622 DEBUG 1 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : Securing GET /
2021-07-20 07:24:34.623 DEBUG 1 --- [nio-8080-exec-6] w.c.HttpSessionSecurityContextRepository : Retrieved SecurityContextImpl [Authentication=OAuth2AuthenticationToken [...]]
2021-07-20 07:24:34.623 DEBUG 1 --- [nio-8080-exec-6] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to SecurityContextImpl [Authentication=OAuth2AuthenticationToken [...]]
2021-07-20 07:24:34.623 DEBUG 1 --- [nio-8080-exec-6] o.s.s.w.s.HttpSessionRequestCache        : Loaded matching saved request http://localhost:8080/
2021-07-20 07:24:34.623 DEBUG 1 --- [nio-8080-exec-6] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorized filter invocation [GET /] with attributes [authenticated]
2021-07-20 07:24:34.623 DEBUG 1 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : Secured GET /
2021-07-20 07:24:34.624 DEBUG 1 --- [nio-8080-exec-6] o.s.s.a.i.a.MethodSecurityInterceptor    : Authorized ReflectiveMethodInvocation: public java.lang.String com.ververica.platform.gateway.controller.Redirects.redirectRoot(); target is of class [com.ververica.platform.gateway.controller.Redirects] with attributes [[authorize: 'permitAll()', filter: 'null', filterTarget: 'null']]
2021-07-20 07:24:34.625 DEBUG 1 --- [nio-8080-exec-6] w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=VvpOidcAuthenticationToken [...] to HttpSession [org.apache.catalina.session.StandardSessionFacade@2b2cdb6c]
2021-07-20 07:24:34.625 DEBUG 1 --- [nio-8080-exec-6] w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=VvpOidcAuthenticationToken [...] to HttpSession [org.apache.catalina.session.StandardSessionFacade@2b2cdb6c]
2021-07-20 07:24:34.625 DEBUG 1 --- [nio-8080-exec-6] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request

From the logs we can see various attributes returned from Azure Active Directory, for example, preferred_username which we use as the login name, and groups which is the groupsClaim. This corresponds to the following values file that was used to set up the OIDC authentication in Ververica Platform:

vvp:
  auth:
    enabled: true
    admins:
      - ...
    oidc:
      groupsClaim: groups 
      ...
      provider:
        userNameAttribute: preferred_username

Use OIDC Debugger

To use the OIDC debugger first add the following additional Redirect URI (aka Callback URL) in the registered client in your OIDC provider, such that the response from the OIDC provider can be sent to the debugger:

https://oidcdebugger.com/debug

Next, find out the authorization_endpoint and token_endpoint of your OIDC provider. You can get it normally from <your issuer-uri>/.well-known/openid-configuration. For example, the issuer-uri of Azure Active Directory is https://login.microsoftonline.com/<tenant>/v2.0 (replace <tenant> with your real one). Then go to the following URL:

https://login.microsoftonline.com/<tenant>/v2.0/.well-known/openid-configuration

you should see

"authorization_endpoint":"https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize"

and

"token_endpoint":"https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token"

(token_endpoint will be used in a later step)

Now, go to the OIDC debugger, set the Authorize URI found above, your registered client ID, the desired scope and click the SEND REQUEST button. You should see a Success! page.

With the information returned from the success page of the OIDC debugger, you can now submit a POST request using your favorite REST API tool (e.g., the Chrome extension Advanced REST Client, Postman, etc.) to your OIDC provider's token endpoint to get the token:

POST 
Content-Type: application/x-www-form-urlencoded
 
grant_type=authorization_code&
code=<the code returned from the OIDC debugger>&
client_id=<your client id>&
client_secret=<your client secret>&
redirect_uri=https%3A%2F%2Foidcdebugger.com%2Fdebug

Finally, you should get a response from your OIDC provider like the following:

{
  "token_type": "Bearer",
  "scope": "openid profile email",
  "expires_in": 3599,
  "ext_expires_in": 3599,
  "access_token": "...",
  "id_token": "..."
}

Decode the returned id_token with JWT. You should see what was included in the id_token which is the token Ververica Platform use for authentication and authorization. For example,

{
  "aud": "...",
  "iss": "https://login.microsoftonline.com/<tenant>/v2.0",
  "iat": 1626766745,
  "nbf": 1626766745,
  "exp": 1626770645,
  "aio": "...",
  "groups": [
    "..."
  ],
  "name": "Jun Qin",
  "nonce": "e5y6mv1gmb",
  "oid": "...",
  "preferred_username": "jun@...",
  "rh": "...",
  "sub": "...",
  "tid": "...",
  "uti": "...",
  "ver": "2.0"
}

Related Information