Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSO Azure AD: Failed to parse server response #8

Closed
Kofl opened this issue Dec 24, 2023 · 38 comments
Closed

SSO Azure AD: Failed to parse server response #8

Kofl opened this issue Dec 24, 2023 · 38 comments

Comments

@Kofl
Copy link

Kofl commented Dec 24, 2023

Hi,

really, really great work on the SSO integration of Vaultwarden.

I try to test the implementation with Azure AD (Entra ID), redirect via login to Microsoft works fine, also redirect back, but then it hangs on Logging in and error log shows:

vaultwarden-VaultWarden-1  | [INFO] Can't read optional SSO public key at data/sso_key.pub.pem : No such file or directory (os error 2)
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:32.895][start][INFO] Rocket has launched from http://0.0.0.0:80
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:43.999][request][INFO] GET /api/config
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:43.999][response][INFO] (config) GET /api/config => 200 OK
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:50.378][request][INFO] GET /api/devices/knowndevice
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:50.384][response][INFO] (get_known_device) GET /api/devices/knowndevice => 200 OK
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:51.767][request][INFO] POST /api/organizations/domain/sso/details
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:51.767][response][INFO] (get_org_domain_sso_details) POST /api/organizations/domain/sso/details => 200 OK
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:51.805][request][INFO] GET /identity/account/prevalidate?domainHint=vaultwarden
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:51.805][response][INFO] (prevalidate) GET /identity/account/prevalidate => 200 OK
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:51.906][request][INFO] GET /identity/connect/authorize?client_id=web&redirect_uri=htt
vaultwarden-VaultWarden-1  | [2023-12-24 16:30:52.504][response][INFO] (authorize) GET /identity/connect/authorize?<data..> => 307 Temporary Redirect
vaultwarden-VaultWarden-1  | [2023-12-24 16:31:11.251][request][INFO] GET /identity/connect/oidc-signin?error=access_denied&error_desc
vaultwarden-VaultWarden-1  | [2023-12-24 16:31:11.251][vaultwarden::api::identity::_][WARN] Query string failed to match route declaration.
vaultwarden-VaultWarden-1  | [2023-12-24 16:31:11.251][vaultwarden::api::identity::_][WARN] missing
vaultwarden-VaultWarden-1  | [2023-12-24 16:31:11.251][response][INFO] (web_files) GET /<p..> [10] => 404 Not Found
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:28.682][request][INFO] GET /api/config
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:28.683][response][INFO] (config) GET /api/config => 200 OK
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:32.624][request][INFO] GET /api/devices/knowndevice
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:32.625][response][INFO] (get_known_device) GET /api/devices/knowndevice => 200 OK
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:33.373][request][INFO] POST /api/organizations/domain/sso/details
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:33.373][response][INFO] (get_org_domain_sso_details) POST /api/organizations/domain/sso/details => 200 OK
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:33.406][request][INFO] GET /identity/account/prevalidate?domainHint=vaultwarden
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:33.406][response][INFO] (prevalidate) GET /identity/account/prevalidate => 200 OK
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:33.481][request][INFO] GET /identity/connect/authorize?client_id=web&redirect_uri=htt
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:33.481][response][INFO] (authorize) GET /identity/connect/authorize?<data..> => 307 Temporary Redirect
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:47.234][request][INFO] GET /identity/connect/oidc-signin?code=0.AV0AgH6F4Y629keCb3DpKM4
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:47.234][response][INFO] (oidcsignin) GET /identity/connect/oidc-signin?<code> => 307 Temporary Redirect
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:48.458][request][INFO] GET /api/config
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:48.458][response][INFO] (config) GET /api/config => 200 OK
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:48.707][request][INFO] POST /identity/connect/token
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:49.122][vaultwarden::sso][ERROR] Failed to contact token endpoint: Failed to parse server response
vaultwarden-VaultWarden-1  | [2023-12-24 16:32:49.123][response][INFO] (login) POST /identity/connect/token => 400 Bad Request
vaultwarden-VaultWarden-1  | [2023-12-24 16:33:07.660][request][INFO] GET /api/config
vaultwarden-VaultWarden-1  | [2023-12-24 16:33:07.660][response][INFO] (config) GET /api/config => 200 OK

Setup below, can I increase the verbose output somehow?

Thanks

services:
  VaultWarden:
    image: simonc/vaultwarden:latest
    env_file: .env
    volumes:
      - ./vaultwarden.sh:/etc/vaultwarden.sh
      - ./bw-data:/data
    ports:
      - 8000:8000

published via Caddy https reverse proxy on https://vault.mydomain.com

.env

ROCKET_PORT=80
DOMAIN=https://vault.mydomain.com
I_REALLY_WANT_VOLATILE_STORAGE=true
SSO_ENABLED=true
SSO_ONLY=true
SSO_CLIENT_ID=from_azure_ad
SSO_CLIENT_SECRET=from_azure_ad
SSO_AUTHORITY=https://sts.windows.net/e1857e80-b68e-47f6-826f-70e928ce3f5d/

As redirect URL on Azure AD: https://vault.mydomain.com/identity/connect/oidc-signin is used.

@Timshel
Copy link
Owner

Timshel commented Dec 26, 2023

Hey,
It fails during the exchange phase to retrieve the token.

This part is handled by the openidconnect-rs lib and it appears that Microsoft do not follow the OIDC spec, cf : ramosbugs/openidconnect-rs#122.

There is some workaround mentioned but at the moment I do not expect to integrate it in the PR since the review is already half blocked due to the complexity.

@Kofl
Copy link
Author

Kofl commented Dec 26, 2023

What a pity that Microsoft is again unable to follow the standards.
In the non-profit space nearly all organizations work with O365 and therefore Azure AD because of the Microsoft sponsoring. So it would be great, to keep it in the backlog.

All the best for the PR, brings vaultwarden a big step forward.

@Kofl
Copy link
Author

Kofl commented Dec 26, 2023

@Timshel Would it be worthwhile for me to look into e.g. Keycloak to relay the authentication to Azure AD and play middleman between Vaultwarden and Azure AD?

@Timshel
Copy link
Owner

Timshel commented Dec 26, 2023

Would it be worthwhile for me

I don't have any input on it other than :

  • Integrating Keycloak with Azure AD appear to be well supported (but I never tried it)
  • Keycloak will work with the PR since I'm testing with it but so does Authelia, authentik ...

@Kofl
Copy link
Author

Kofl commented Dec 27, 2023

Great success.

I used Keycloak as Identity broker and it worked like a charm.

It was sufficient to add Entra ID as default Identity Provider and Vaultwarden as client. in Keycloak. And voila, everything fine.

So from my point of view I am fine with the solution as Microsoft didn't fix it for over 3 years and so we dont have to add additional burdens on the PR.

Hopefully the solution will also be helpful to others who use (or must use) Entra ID as an identity provider.

@ocdi
Copy link

ocdi commented Dec 27, 2023

This is weird, I'm using Entra ID with my setup and it's works, quite well. I've got 25 users and we have the setting to requirec login with sso.

@Kofl
Copy link
Author

Kofl commented Dec 27, 2023

This is weird, I'm using Entra ID with my setup and it's works, quite well. I've got 25 users and we have the setting to requirec login with sso.

Did you also use the image simonc/vaultwarden:latest for testing?

@ocdi
Copy link

ocdi commented Dec 27, 2023

I built my own image from source. Months ago I originally started with an earlier version of the SSO pr and updated it but I'm pretty sure I'm just using the code from this repo.

This was the last time I pulled the code, I was swapping branches so I could compare/reconcile the db migrations.

https://github.com/ocdi/vaultwarden/commits/tim-sso-support

@Kofl
Copy link
Author

Kofl commented Dec 27, 2023

Interesting, do you also use the same endpoint?

SSO_AUTHORITY=https://sts.windows.net/Entra-ID/

@ocdi
Copy link

ocdi commented Dec 27, 2023

Ah no I'm using the one starting with

https://login.microsoftonline.com/

@ocdi
Copy link

ocdi commented Dec 27, 2023

I checked the config and I'm using

https://login.microsoftonline.com/tenantguid/v2.0

@sandervandegeijn
Copy link

sandervandegeijn commented Dec 28, 2023

Was referred to this thread. Is it just a matter of using https://login.microsoftonline.com/tenantguid/v2.0
as the SSO_AUTHORIT? Will try tomorrow if I can.

We have access to premier support, I can try to open a ticket on this with Microsoft but I don't have a clear understanding of what is amiss at the AzureAD side.

@Kofl
Copy link
Author

Kofl commented Dec 28, 2023

It seems so, that the v2 endpoint https://login.microsoftonline.com/tenantguid/v2.0 should work.
I will give it a try also later today.

(https://learn.microsoft.com/en-us/entra/fundamentals/how-to-find-tenant)

@Kofl
Copy link
Author

Kofl commented Dec 28, 2023

Awesome, it works <:o)

.env

ROCKET_PORT=80
DOMAIN=https://v.mydomain.com
I_REALLY_WANT_VOLATILE_STORAGE=true
SSO_ENABLED=true
SSO_ONLY=true
SSO_CLIENT_ID=XXXXXXXXXXXXXXXXXXXXXXXX
SSO_CLIENT_SECRET=YYYYYYYYYYYYYYYYYYYYYY
SSO_AUTHORITY=https://login.microsoftonline.com/tenantguid/v2.0

So its the magic of v2 endpoint at https://login.microsoftonline.com/tenantguid/v2.0
v1 (no v2.0 at the end) generates the same error as reported.

@ocdi
Copy link

ocdi commented Dec 28, 2023

Great result. We should perhaps update the doc in the pr to give the tip regarding entra id, make sure you use the v2 endpoint.

@Blackclaws
Copy link

As far as I am aware v1 should only be used for Entra Id specific applications anyway. Microsoft itself recommends to only use v2 for external applications and uses that one mainly in their documentation.

@sandervandegeijn
Copy link

Ah, then it's not worth opening a ticket with Microsoft about this. We use this base url for other types of flows as well. It's a bit awkward but it does work.

Will try to verify as well.

@Blackclaws
Copy link

Ah, then it's not worth opening a ticket with Microsoft about this. We use this base url for other types of flows as well. It's a bit awkward but it does work.

Will try to verify as well.

https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc

If you follow the guide it will point you to the v2 endpoint.

@Kofl
Copy link
Author

Kofl commented Dec 28, 2023

Some hint in the doc would be great to minimize support requests.

Easiest way to retrieve the individual v2 endpoint:

https://entra.microsoft.com/
Identity | Applications | App registrations | Endpoints -> OpenID Connect metadata document
(remove the "/.well-known/openid-configuration" part)

@Timshel
Copy link
Owner

Timshel commented Dec 28, 2023

@Kofl updated the doc with your details, thx :)

@Kofl
Copy link
Author

Kofl commented Dec 30, 2023

@sandervandegeijn So far it works for all of us. Did you have time to verify it on your side?

@sandervandegeijn
Copy link

Not entirely, I think our IAM-team forgot to check one option on the Azure side. Unfortunately I can't change this myself and it's new years eve this weekend. Give me a couple of days :)

@sandervandegeijn
Copy link

sandervandegeijn commented Jan 2, 2024

The scopes in the docs were very helpful, but I'm still running into a problem:

image image

We have configured the scopes as per the docs, but running into this error. Clicking the return to application gives a 404 and errors in the logs:

│ [2024-01-02 08:50:57.507][vaultwarden::api::identity::][WARN] Query string failed to match route declaration. │
│ [2024-01-02 08:50:57.507][vaultwarden::api::identity::
][WARN] missing │
│ [2024-01-02 08:50:57.508][response][INFO] (web_files) GET /<p..> [10] => 404 Not Found

@Kofl
Copy link
Author

Kofl commented Jan 2, 2024

For us in the enterprise app permissions it was fine to only set as below. Didnt touch scopes at all.

image

@sandervandegeijn
Copy link

It was de admin that needed to set the right consent property. After that, it's working like a charm! The only exception is that the return url in the error screens goes to a page that doesn't exist on vaultwarden.

@Kofl
Copy link
Author

Kofl commented Jan 3, 2024

Great.

Which return urls in which error screens?

@sandervandegeijn
Copy link

The bottom link in this screenshot:

image

Returns to vaulwarden but gives a 404.

@Kofl
Copy link
Author

Kofl commented Jan 3, 2024

Shouldnt that link redirct to Entra ID to confirm as global administrator the application for all users?

When the consent is set right, the message above should never appear and no user get bothered with it, or?

@sandervandegeijn
Copy link

It's not visible in the default flow idd, it only shows when there is an error. The link points to: https://vaultwarden.url/identity/connect/oidc-signin?error=access_denied&error_subcode=cancel&state=xxxxxx

@ArturKokoszka
Copy link

[INFO] Can't read optional SSO public key at data/sso_key.pub.pem : No such file or directory (os error 2)
[2024-01-04 14:09:45.546][start][INFO] Rocket has launched from http://0.0.0.0:80
[2024-01-04 14:10:15.488][request][INFO] GET /api/config
[2024-01-04 14:10:15.488][response][INFO] (config) GET /api/config => 200 OK
[2024-01-04 14:10:18.310][request][INFO] GET /api/devices/knowndevice
[2024-01-04 14:10:18.311][response][INFO] (get_known_device) GET /api/devices/knowndevice => 200 OK
[2024-01-04 14:10:19.623][request][INFO] POST /api/organizations/domain/sso/details
[2024-01-04 14:10:19.624][response][INFO] (get_org_domain_sso_details) POST /api/organizations/domain/sso/details => 200 OK
[2024-01-04 14:10:19.671][request][INFO] GET /identity/account/prevalidate?domainHint=vaultwarden
[2024-01-04 14:10:19.674][response][INFO] (prevalidate) GET /identity/account/prevalidate => 200 OK
[2024-01-04 14:10:19.740][request][INFO] GET /identity/connect/authorize?client_id=web&redirect_uri=htt
[2024-01-04 14:10:20.282][response][INFO] (authorize) GET /identity/connect/authorize?<data..> => 307 Temporary Redirect
[2024-01-04 14:10:20.631][request][INFO] GET /identity/connect/oidc-signin?code=0.ARAAyW6C-EcQXUy9FRfHPX8
[2024-01-04 14:10:20.631][response][INFO] (oidcsignin) GET /identity/connect/oidc-signin?<code> => 307 Temporary Redirect
[2024-01-04 14:10:22.880][request][INFO] GET /api/config
[2024-01-04 14:10:22.880][response][INFO] (config) GET /api/config => 200 OK
[2024-01-04 14:10:22.894][request][INFO] POST /identity/connect/token
[2024-01-04 14:10:23.214][vaultwarden::sso][ERROR] Failed to contact token endpoint: Server returned error response
[2024-01-04 14:10:23.214][response][INFO] (login) POST /identity/connect/token => 400 Bad Request

No idea why, but same behavior (using the v2.0 endpoint). Also tried using main and sso-support branches, no difference. This is the environmnet section of my compose file:

      - ADMIN_TOKEN=[hidden]
      - ROCKET_PORT=80
      - DOMAIN=https://vaultwarden.mydomain
      - SSO_ENABLED=true
      - SSO_ONLY=true
      - SSO_CLIENT_ID=[from entra]
      - SSO_CLIENT_SECRET=[from entra]
      - SSO_AUTHORITY=https://login.microsoftonline.com/[mytenantid]/v2.0

Did I miss simething or do you guys also face this problem?

@Timshel
Copy link
Owner

Timshel commented Jan 4, 2024

It's not visible in the default flow idd, it only shows when there is an error. The link points to: https://vaultwarden.url/identity/connect/oidc-signin?error=access_denied&error_subcode=cancel&state=xxxxxx

Yes the endpoint was made to handle only the happy case.
Looking around it appears that redirecting with error and error_description are the norm and defined in the spec ( https://openid.net/specs/openid-connect-core-1_0.html 3.1.2.6. Authentication Error Response). So will try to make something cleaner.

@ArturKokoszka it appears the exchange of the return code for the id_token and access_token fail.
Maybe running with LOG_LEVEL=debug will give you more information ?

@ArturKokoszka
Copy link

Sorry for bothering you, I just recreated secret in Entra and the new value worked like a charm. Probably the old one contained a problematic character that wasn't properly parsed on some stage or something.
Please note that on sso-support branch the startup.sh script doesn't incluse support for SSO_FRONTEND value.

@Timshel
Copy link
Owner

Timshel commented Jan 4, 2024

@ArturKokoszka

Sorry for bothering you, I just recreated secret in Entra and the new value worked like a charm. Probably the old one contained a problematic character that wasn't properly parsed on some stage or something.

Do you still have the old secret value ? I could test it to check if I find a failure.
Might be that using simple quote when adding the secret to the conf prevent the issue.

Please note that on sso-support branch the startup.sh script doesn't incluse support for SSO_FRONTEND value.

Yes the SSO_FRONTEND is specific to the main branch since it allows to use the custom front-end builds.

@Timshel
Copy link
Owner

Timshel commented Jan 5, 2024

Hey,
As mentioned in my latest comment in the PR added some logic to better handle error and error_description.

As mentioned the cleaner version relies on another patch to the frontend so you'll have to run the main branch with the override version of Timshel/oidc_web_builds.

@ArturKokoszka
Copy link

No, sorry, I don't have the old value, but I remember that it contained a dot .. On the main branch everything works perfectly. Thnak you for yout work.

@sandervandegeijn
Copy link

This seems okay on my side.

@Timshel
Copy link
Owner

Timshel commented Jan 18, 2024

@Kofl working on your side ? :)

@Kofl
Copy link
Author

Kofl commented Jan 19, 2024

@Timshel all working fine, thanks

@Timshel Timshel closed this as completed Jan 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants