Web UI SSO with Azure AD - not working

Hello,

Trying to set up Web UI SSO with Azure AD, but having an issue integrating with the Temporal backend.

All Temporal components are deployed with the Helm chart. The UI is accessed from the localhost via kubectl port-forward.

The following environment variables are set for the server deployment:

        - name: TEMPORAL_AUTH_AUTHORIZER
          value: default
        - name: TEMPORAL_AUTH_CLAIM_MAPPER
          value: default
        - name: TEMPORAL_JWT_KEY_SOURCE1
          value: 'https://login.microsoftonline.com/common/discovery/v2.0/keys'
        - name: TEMPORAL_JWT_PERMISSIONS_CLAIM
          # Take Temporal permissions from the standard AD roles attribute
          value: roles

The following environment variables are set for the Web UI deployment:

        - name: TEMPORAL_AUTH_ENABLED
          value: 'true'
        - name: TEMPORAL_AUTH_PROVIDER_URL
          value: https://login.microsoftonline.com/xxxxx
        - name: TEMPORAL_AUTH_ISSUER_URL
          value: https://sts.windows.net/xxxxx
        - name: TEMPORAL_AUTH_CLIENT_ID
          value: <client ID>
        - name: TEMPORAL_AUTH_CLIENT_SECRET
          value: <client secret>
        - name: TEMPORAL_AUTH_CALLBACK_URL
          value: http://localhost:8080/auth/sso/callback
        - name: TEMPORAL_AUTH_SCOPES
          value: openid,profile,email
        - name: TEMPORAL_CODEC_PASS_ACCESS_TOKEN
          value: 'true'

After clicking Continue to SSO in the Web UI, I see authorization code flow progressing in the Network tab of the browser.

In particular, I see

  • Authorization code is returned to the callback URL: GET http://localhost:8080/auth/sso/callback?code=
  • AuthUser.idToken is stored in browser’s local storage: (appears well-formed, can be validated and parsed)
  • AuthUser.accessToken is stored in browser’s local storage: (looks malformed to me)
  • Request to the backend (api/v1/namespaces) is sent with the access token in Authorization header and the ID token in the Authorization-Extras header
  • Request is rejected by the backend with the message in log “Authorization error”,“error”:“token contains an invalid number of segments”

Apparently the backend also considers the access token malformed.

Could you please advise what we are doing wrong ? Are there any means to further debug the flow ? Is it AD that returns the malformed token or is the token transformed by the UI server in some way ?

Thanks

Hi, I just got SSO working with Azure AD.

You need to setup the App Registration a specific way for it to work. Apparently MS’s implementation of oidc is slightly different.

See this answer: validation - Invalid signature while validating Azure ad access token, but id token works - Stack Overflow

Notably you need to specify a custom API name value for the TEMPORAL_AUTH_SCOPES value

Hi @Extant-1, thanks for your reply.

It seems my situation is slightly different. It’s not just the signature of the access token that fails to validate. The string sent in the Authorization header does not looks like a JWT token at all:

Authorization: Bearer PAQABAAAAAAD… (rest of the token trimmed by me)

If possible, could you please share your setup ? Are there any notable differences compared to my setup (described above), except for the TEMPORAL_AUTH_SCOPES value ?

Which Web UI version works for you ? I am trying to configure v2.9.0.

Thanks

This is my setup, running Temporal 1.19.1 and Web 2.9.0

Granted, I never tried getting it working through port-forward only via an ingress route.

Web:

       - name: TEMPORAL_AUTH_ENABLED
          value: "true"
        - name: TEMPORAL_AUTH_PROVIDER_URL
          value: https://login.microsoftonline.com/<tenant-id>/v2.0
        - name: TEMPORAL_AUTH_CLIENT_ID
          value: <app registration client id>
        - name: TEMPORAL_AUTH_CLIENT_SECRET
          value: <app registration client secret>
        - name: TEMPORAL_AUTH_CALLBACK_URL
          value: https://temporal.${hostname}/auth/sso/callback
        - name: TEMPORAL_AUTH_SCOPES
          value: openid,profile,email,<app registration client id>/Read 

Frontend configmap

│ global:                                                                                                                                                                                                                               │                                                                                                                                                                                 
│   authorization:                                                                                                                                                                                                                      │
│     authorizer: default                                                                                                                                                                                                               │
│     claimMapper: default                                                                                                                                                                                                              │
│     permissionsClaimName: roles                                                                                                                                                                                                       │
│     jwtKeyProvider:                                                                                                                                                                                                                   │
│       keySourceURIs:                                                                                                                                                                                                                  │
│       - https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys        

Hope that helps.

Hi @Extant-1,

Thanks for sharing the configuration. My first issue was that I was missing v2.0 in the AUTH_PROVIDER URL, that’s probably the reason for the malformed token.

The second issue was that my custom scope had to be specified in the AUTH_SCOPES, in addition to the three default ones.

The SSO works now.

Thanks again !