doy / rbw

unofficial bitwarden cli
https://git.tozt.net/rbw
Other
573 stars 82 forks source link

Add support for SSO login #174

Closed dezeroku closed 2 weeks ago

dezeroku commented 1 month ago

Resolves https://github.com/doy/rbw/issues/118

Implementation is mostly ported from the official CLI, with minor changes to utilise having predefined sso_id in the config file.

Tested with Google based SSO.

Auth flow

Can be summarised with:

  1. Generate two random values, state and ssoCodeVerifier
  2. hash and B64 escape the ssoCodeVerifier
  3. spin up a local callback server (I assume port range is important here because of the allowed redirect_uris on Bitwarden end)
  4. open a webbrowser initializing the SSO flow using the previously generated values
  5. obtain the authorization_code via the callback server
  6. replace the code for tokens by calling the /identity/token endpoint (same as for passwords, but different params)

Quirks

2FA

Due to the way 2FA is implemented in rbw (try to authenticate without 2FA, fallback to it as needed based on the response from server) SSO users with 2FA configured have to go through the "webbrowser flow" twice: once to get the response about the missing 2FA, second time to send 2FA alongside the SSO obtained code. Bitwarden CLI reuses the authorization_code obtained in first iteration in such cases, but I feel this approach would require bigger overhaul in rbw.

Password

SSO flow doesn't use the master password in its auth, so theoretically we don't have to ask for it during login. Of course it's still required for the unlock operation.

I kept the master password prompt in SSO flow to be in sync with the password flow, which automatically calls unlock after login.

Notes

Usual disclaimer: I don't really write Rust, feel free to suggest more idiomatic code wherever you see fit. Especially the error handling feels like it could use some improvements