Code Monkey home page Code Monkey logo

Comments (41)

jyio avatar jyio commented on June 23, 2024 17

Thank you for sharing this interesting app! It already beats NocoDB and Baserow for me because it supports nested formulas. Good stuff.

I just got it working with Keycloak 17. It's a complicated beast that supports multiple multiple realms and protocols. Some things were not obvious to me (as a noob to Grist, Keycloak, and SAML)...

I already had a realm and user, so I only needed to create a Grist-specific SAML client:

  • The Client ID in Keycloak should be https://<grist-host>/saml/metadata.xml
  • Keycloak needs to know where to redirect after login/logout
    • Allow redirecting after login by setting the Valid Redirect URIs to https://<grist-host>/*
    • Enable redirecting after logout by setting the Logout Service Redirect Binding URL (under Fine Grain SAML Endpoint Configuration)
  • Protocol mappers are needed; the builtin mappers work, but their SAML attribute names should be changed to work with SAML2-js:
    • givenName: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
    • surname: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
    • email: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress

Grist needs the following information from Keycloak:

  • The SAML login/logout URL in Keycloak 17 is https://<keycloak-host>/realms/<realm>/protocol/saml (in Keycloak 16, it would've been https://<keycloak-host>/auth/realms/<realm>/protocol/saml; note the /auth)
  • The client's private key and certificate could be obtained from the Installation tab (on the client page)
  • Keycloak's server (realm) certificate could be obtained from Realm Settings in the General tab behind SAML 2.0 Identity Provider Metadata
  • These keys and certificates should be placed in files accessible to Grist (as indicated in SamlConfig.ts) with appropriate PEM headers/footers:
    • -----BEGIN RSA PRIVATE KEY-----/-----END RSA PRIVATE KEY-----
    • -----BEGIN CERTIFICATE-----/-----END CERTIFICATE-----

Here's how I start Grist (behind a reverse-proxy):

URL="https://<grist-host>"
SAML="https://<keycloak-host>/realms/<realm>/protocol/saml"
docker run -d --name=grist \
  -e GRIST_SINGLE_ORG=docs \
  -e APP_HOME_URL="${URL}" \
  -e APP_DOC_URL="${URL}" \
  -e GRIST_SAML_SP_HOST="${URL}" \
  -e GRIST_SAML_SP_KEY=/persist/saml/client.key \
  -e GRIST_SAML_SP_CERT=/persist/saml/client.crt \
  -e GRIST_SAML_IDP_LOGIN="${SAML}" \
  -e GRIST_SAML_IDP_LOGOUT="${SAML}" \
  -e GRIST_SAML_IDP_CERTS=/persist/saml/idp.crt \
  -e GRIST_SAML_IDP_UNENCRYPTED=1 \
  -v grist-data:/persist \
  -p 8484:8484 \
  gristlabs/grist

Oh... and if you, like me, are tempted to upgrade Keycloak from 16 to 17... it's a tarp! There are significant changes, so look before you leap.

I hope this helps someone. And yes, OIDC would be nice too, but I totally understand that you're scrambling to fix bugs after posting this on Reddit.

from grist-core.

Gatherix avatar Gatherix commented on June 23, 2024 6

We use LDAP and OIDC internally, would be helpful not having to setup a SAML provider

from grist-core.

paulfitz avatar paulfitz commented on June 23, 2024 4

SAML support is now available. We'll need to do a write-up on how to configure it, but there is documentation at https://github.com/gristlabs/grist-core/blob/main/app/server/lib/SamlConfig.ts

from grist-core.

apollo13 avatar apollo13 commented on June 23, 2024 4

It would be nice if something simple like Authelia would be supported. That would mean reading headers like Remote-User, Remote-Groups, Remote-Name, Remote-Email from the request (preferably configurable). This would enable a wider range of integration with existing login solutions and would allow people to try grist easier. I imagine that it would be relatively little code to add and probably also result in more people to be able to try grist (and maybe less support requests because SAML is a beast).

For instance I wanted to see how far I can take self-hosted currently, but I haven't been able to figure out whether teams are supported locally or one can just share with 2 members. I guess I will manage to setup SAML at some point to check that out :)

from grist-core.

paulfitz avatar paulfitz commented on June 23, 2024 2

I posted a template for self-hosting Grist using traefik-forward-auth. Looks like it has OIDC support. Could be worth trying hooking it up to one of @almereyda's suggestions.

from grist-core.

nycanit avatar nycanit commented on June 23, 2024 2

This month Google posted this blog about their support for the Passkey standard alongside Apple and Microsoft:
https://blog.google/technology/safety-security/the-beginning-of-the-end-of-the-password/
"And today, ahead of World Password Day, we’ve begun rolling out support for passkeys across Google Accounts on all major platforms. They’ll be an additional option that people can use to sign in, alongside passwords, 2-Step Verification (2SV), etc."

Passkey gives the option of signup and signin using Apple FaceID, Android fingerprint or Windows Hello (Face, fingerprint etc). Currently two webauthn libraries support Passkey - webauthn_rs in rust and simplewebauthn in typescript:
https://passkeys.dev/docs/tools-libraries/libraries/

Here is a demo put up by webauthn_rs that let me both sign up and sign in using fingerprint on macbook:
https://webauthn.firstyear.id.au/

For notebooks that don't have a fingerprint sensor you can use an Iphone FaceID or Android fingerprint sensor. The demo also supports secure Fido keys from Yubico and others:
https://www.amazon.com/Yubico-YubiKey-Factor-Authentication-Security/dp/B07HBCTYP1

And then have passwords and oauth fallback for those who prefer not to get too fancy. Biometrics would be a nice way to log into grist.

from grist-core.

paulfitz avatar paulfitz commented on June 23, 2024 1

Seems reasonable @almereyda. We have SAML support on the way, for people wanting to use Grist with their SSO.

from grist-core.

paulfitz avatar paulfitz commented on June 23, 2024 1

Authentik looks like a decent self-hosted sso solution. I just tested it and it works well with Grist, using SAML.

from grist-core.

paulfitz avatar paulfitz commented on June 23, 2024 1

Update: Grist and Dex (https://dexidp.io/) work particularly well together and allow a variety of login solutions to be configured pretty easily. I'm making a demo/template at https://github.com/gristlabs/grist-omnibus, and would be interested in feedback.

from grist-core.

viniciusao avatar viniciusao commented on June 23, 2024 1

Hi @viniciusao, are your settings along the lines suggested in https://support.getgrist.com/install/saml/#example-authentik ? Particularly GRIST_SAML_IDP_LOGIN and GRIST_SAML_IDP_LOGOUT?

Turns out it was the SAML provider authorization flow type, I've set to "explicit consent", now I changed to "implicit".

from grist-core.

almereyda avatar almereyda commented on June 23, 2024

A common way of implementing authentication, without having to provide local authentication (similar to what @outline does), is to make use of the Passport.js ecosystem, providing some OIDC adapters by default, with the option the extend these with other authentication adaptor plugins.

from grist-core.

FVilli avatar FVilli commented on June 23, 2024

I'm trying to setup grist self-hosted with authentik (docker).
//docker-compose
environment:
- DEBUG=1
- GRIST_SAML_IDP_SKIP_SLO
- GRIST_SAML_SP_HOST=https://grist.#my-domain#.cloud
- GRIST_SAML_IDP_UNENCRYPTED=1
- GRIST_SAML_IDP_LOGIN=https://auth.#my-domain#.cloud
- GRIST_SAML_IDP_LOGOUT=https://auth.#my-domain#.cloud
- GRIST_SAML_IDP_CERTS=/certificates/authentikSelf-signedCertificate_certificate.pem
- GRIST_SAML_SP_KEY=/certificates/GristAppCertificate_certificate.pem
- GRIST_SAML_SP_CERT=/certificates/GristAppCertificate_private_key.pem
...
all behind traefik reverse-proxy

In the browser console log:

Mixed Content: The page at 'https://grist.#my-domain#.cloud/o/docs/' was loaded over HTTPS, but requested an insecure resource 'http://grist.#my-domain#.cloud:8484/o/docs/api/session/access/active'. This request has been blocked; the content must be served over HTTPS.

So the domain appears to be correct but http and port aren't ....
Can I solve this issue with some configuration (env) ?

from grist-core.

paulfitz avatar paulfitz commented on June 23, 2024

Hi @FVilli, try setting the variables mentioned in #117 (comment):

One thing you could try is to set environment variables APP_DOC_URL and APP_HOME_URL to whatever way your site will be accessed by the user. If your site is now at https://example.com, you would set those two variables to that (including the https).

from grist-core.

paulfitz avatar paulfitz commented on June 23, 2024

Thanks a lot for posting that @jyio!

from grist-core.

helmut72 avatar helmut72 commented on June 23, 2024

Header-based authentication would be great. Then everyone can use the preferred reverse proxy. For me it's Caddy with caddy-security, for apollo13 it's Authelia. Most of the self-hosted admins use a reverse proxy.

from grist-core.

helmut72 avatar helmut72 commented on June 23, 2024

@jyio can you post your complete Grist and Keycloak configuration please? I don't get a login page in Keycloak. Never used Keycloak for SAML, only some trials with OAuth (which worked). Thank you!

Edit:
Finally it works also for me with Keycloak. Also for Grist I was unsure about the login url for saml. Here is my saml config for Grist:

GRIST_SAML_SP_HOST=https://grist.example.com
GRIST_SAML_SP_KEY=/saml/sp.key
GRIST_SAML_SP_CERT=/saml/sp.crt

GRIST_SAML_IDP_LOGIN=https://keycloak.example.com/auth/realms/<my grist realm>/protocol/saml
GRIST_SAML_IDP_LOGOUT=https://keycloak.example.com/auth/realms/<my grist realm>/protocol/saml # doesn't work
GRIST_SAML_IDP_UNENCRYPTED=1
GRIST_SAML_IDP_CERTS=/saml/idp.crt

In Keycloak I also needed Valid Redirect URIs: https://grist.example.com/*. Rest of the Keycloak configuration is default after creating a new realm and adding one test user plus the informations from jyio.

from grist-core.

jyio avatar jyio commented on June 23, 2024

Glad you got it working, @helmut72. Thank you for sharing your config! I just added my Grist config above.

I'm relatively new to Keycloak also. Because I recently installed 17.0.0, my login and logout URLs were both https://<keycloak-host>/realms/public/protocol/saml (note: no /auth, which was in 16..).

The logout does work (you get logged out from Grist and Keycloak) but Keycloak doesn't know where to redirect you after logging out. I set Logout Service Redirect Binding URL to https://<grist-host>/.

Protip: If you set Root URL to https://<grist-host>, then Valid Redirect URIs could be just /* and Logout Service Redirect Binding URL could be /.

from grist-core.

helmut72 avatar helmut72 commented on June 23, 2024

Thank you, @jyio. Now logout also works. Great experience this weekend, one is Grist, second is learning basics about SAML. Now need to dive deeper into both.

from grist-core.

dumblob avatar dumblob commented on June 23, 2024

Or maybe not overcomplicate things and just "integrate" with bitwarden (client is open source; server not but there is a very good open source reimplementation https://github.com/dani-garcia/vaultwarden/ ) and other (less secure but also widely used) credentials vaults.

Of course it misses some goodies (w3c/webappsec-change-password-url#34 , dani-garcia/vaultwarden#1691 ) but even then it proves to be the top approach to login management.

from grist-core.

helmut72 avatar helmut72 commented on June 23, 2024

Bitwarden/Vaultwarden isn't an authentication product, but a password manager. Can't be used for this part.

from grist-core.

dumblob avatar dumblob commented on June 23, 2024

@helmut72 that was the point. Use some whatever internal infrastructure for login & roles management but expose only the minimum - i.e. login + password. Let everything else up to the password manager.

from grist-core.

jyio avatar jyio commented on June 23, 2024

Are you suggesting to use vaultwarden as some sort of centralized identity store, so Grist would just collect the credentials (from a login page) and verify them against vaultwarden? That's an interesting way to use vaultwarden... do you have any references for that?

Alternatively, just integrate with LDAP or AD, which are battle-tested for this case, but admittedly "enterprisey" (if you thought SAML was complicated). Or implement OIDC/OAuth2, which opens the door to an entire world of external identity providers (such as GitHub, Twitter, or Facebook). Or -- stay with me here -- configure Keycloak to consult an LDAP/AD server or delegate to an external SAML/OIDC provider, so you outsource the login as well as the identity.

from grist-core.

helmut72 avatar helmut72 commented on June 23, 2024

@dumblob A password manager is no user management tool. With a password manager you save login informations for your self hosted services and other services like Github or your outlook.com account or whatever, but you don't have created this user accounts in Bit/Vaultwarden.

from grist-core.

dumblob avatar dumblob commented on June 23, 2024

@dumblob A password manager is no user management tool. With a password manager you save login informations for your self hosted services and other services like Github or your outlook.com account or whatever, but you don't have created this user accounts in Bit/Vaultwarden.

This was my point because Bitwarden actually does support identity management (incl. hierarchies, permissions, etc.).

This whole idea comes down to the fact, that a client anyway needs some password manager in practice. So why to run/maintain/interface_with SAML/... server (which is really complicated) if clients anyway need* a password manager with identity support (like the Bitwarden client). So in practice you either need to synchronize the identity hierarchy + permissions

  1. between SAML server and password manager clients
  2. or between Grist and password manager clients

The difference being you already have Grist installed & configured (password manager server like Vaultwarden doesn't need to be installed & maintained by you - it's not a requirement contrary to the SAML/... solution).

An ideal solution would be if password manager servers would support SAML, OAuth, etc. But we're not yet there.

Don't take me wrong - I totally understand Grist utterly needs an enterprise-level architecture (sooner or later). So SAML & OAuth is definitely the way to go. I've just mentioned "password managers" as an alternative for those not wanting to have the hassle with Keycloak etc.


* yes, it'd have the nice side effect of pushing Grist users to use password managers as that's generally the safest known solution to credentials management

from grist-core.

almereyda avatar almereyda commented on June 23, 2024

After watching the conversation for a while, a similar discussion in another projects comes to my mind. Next to the creative attempts in rethinking use cases for password managers, derived from that other train of thought, I would second the notion that standards-compliant authentication protocals, such as SAML and OIDC, are useful for enabling generic usage of grist in standardised environments.

In the issue over at https://github.com/outline/outline/issues/1881 people have shown to provide very lean and minimal Identity and Access Management services soley for the purpose of emulating "local authentication". They are:

OIDC will prove to be a useful addition to grist, then.

from grist-core.

helmut72 avatar helmut72 commented on June 23, 2024

Will this also use forward auth? This means that public sharing isn't possible?

from grist-core.

paulfitz avatar paulfitz commented on June 23, 2024

@helmut72 it uses forward auth internally, on particular login/logout related endpoints. Auth on other pages is via a cookie. So public sharing should be possible. If the forwarding were coming from an external source that is handling other web applications, or offers an independent way to login/logout, then there will be the problem of inconsistencies you hit in #207, which can be fixed but at the cost of public sharing becoming awkward. A special prefix for public sharing will be important to square that circle.

from grist-core.

helmut72 avatar helmut72 commented on June 23, 2024

it uses forward auth internally, on particular login/logout related endpoints.

Shouldn't it then also works with Caddy and Authelia? I've looked into our Omnibus:
https://github.com/paulfitz/grist-omnibus/blob/main/traefik.yaml

You only catch /auth/login and /_oauth in Traefik to use Dex. When I do this with Caddy and Authelia and logout in Grist, user {http.reverse_proxy.header.Remote-Email} is logged in Grist. Shouldn't it work if Grist notice that Remote-Email is empty and do whatever is needed to recognize that there isn't a signed-in user anymore?

from grist-core.

paulfitz avatar paulfitz commented on June 23, 2024

Shouldn't it then also works with Caddy and Authelia? I've looked into our Omnibus: https://github.com/paulfitz/grist-omnibus/blob/main/traefik.yaml
You only catch /auth/login and /_oauth in Traefik to use Dex. When I do this with Caddy and Authelia and logout in Grist, user {http.reverse_proxy.header.Remote-Email} is logged in Grist. Shouldn't it work if Grist notice that Remote-Email is empty and do whatever is needed to recognize that there isn't a signed-in user anymore?

@helmut72 something sounds off there. If I'm understanding correctly, when you have Grist with Caddy and Authelia, logging out using the "Sign Out" option in Grist is not working, it is leaving you logged in? There is a GRIST_FORWARD_AUTH_LOGOUT_PATH variable that is important here. For the omnibus it gets set to _oauth/logout, so that Grist will call traefik-forward-auth to actually sign out. And then traefik-forward-auth takes LOGOUT_REDIRECT=.../signed-out to come back to Grist afterwards.

from grist-core.

helmut72 avatar helmut72 commented on June 23, 2024

@paulfitz Thanks, interesting how it works with Traefik and Dex.

But my problem: The user called {http.reverse_proxy.header.Remote-Email} is logged in without hitting any login or logout. I only open grist.example.com.

I really wish Grist just supports OIDC next to SAML or header auth with an own path for public shared links.

from grist-core.

viniciusao avatar viniciusao commented on June 23, 2024

Authentik looks like a decent self-hosted sso solution. I just tested it and it works well with Grist, using SAML.

@paulfitz I tried authentik and grist, it does indeed work, but when I sign out from grist I'm redirected to authentik login page and then is not possible to logging into grist again.

from grist-core.

paulfitz avatar paulfitz commented on June 23, 2024

Hi @viniciusao, are your settings along the lines suggested in https://support.getgrist.com/install/saml/#example-authentik ? Particularly GRIST_SAML_IDP_LOGIN and GRIST_SAML_IDP_LOGOUT?

from grist-core.

viniciusao avatar viniciusao commented on June 23, 2024

Hi @viniciusao, are your settings along the lines suggested in https://support.getgrist.com/install/saml/#example-authentik ? Particularly GRIST_SAML_IDP_LOGIN and GRIST_SAML_IDP_LOGOUT?

yes, I sign out grist, then sign out authentik and did the same login process but authentik returns "Whoops!
Something went wrong! Please try again later." after clicking on "redirecting to grist".

from grist-core.

Chluz avatar Chluz commented on June 23, 2024

Hi, sorry for bringing the keycloak config question, as detailed by @jyio, back up a year later. I've configured Grist and Keycloak as listed above, but even with the correct mappers in place in Keycloak, my username is being picked up as the user identifier instead of the email. This is despite setting the userID setting in the Keycloak client to email.
This then means I have to set GRIST_DEFAULT_EMAIL to my username (rather than my email) to be identified as the original team owner.
Could someone share their Keycloak mappings to make sure I got them right before digging deeper ? Thanks in advance,

from grist-core.

helmut72 avatar helmut72 commented on June 23, 2024

@Chluz The mappers in this post works for me: #44 (comment)

Bildschirmfoto 2023-04-10 um 21 53 46

Details:
Bildschirmfoto 2023-04-10 um 21 56 01

from grist-core.

Chluz avatar Chluz commented on June 23, 2024

@Chluz The mappers in this post works for me: #44 (comment)

Bildschirmfoto 2023-04-10 um 21 53 46

Details: Bildschirmfoto 2023-04-10 um 21 56 01

Thank you, the snapshot showing the SAML Attribute name as a URI was what needed - I had previoulsy tried to use the names from #44 (comment) , not knowing URIs also could be used.

For those looking to replicate this, the easiest is to go to your "client scope" tab in keycloak, click the dedicated scope for that client, add mapper, predefined mapper, and add the 3 X500 example you have. Then edit each one to replace the SAML attribute name field with the appropriate URI from #44 (comment)

Thanks again !

from grist-core.

helmut72 avatar helmut72 commented on June 23, 2024

And then have passwords and oauth fallback for those who prefer not to get too fancy. Biometrics would be a nice way to log into grist.

This is supported for years with the IDP Keycloak. You don't enable webauthn on apps that use modern authentication like Grist, but on the IDP.

from grist-core.

raph avatar raph commented on June 23, 2024

@nycanit zitadel support webauthn / fido2 passkey standard and also SAML, i'm looking into setting it up

from grist-core.

gotjoshua avatar gotjoshua commented on June 23, 2024

wondering if anyone managed to get grist working with https://github.com/logto-io/logto ? seems like it could be another option

from grist-core.

mishaoljaca avatar mishaoljaca commented on June 23, 2024

Hello community,

I am currently working on setting up SAML-based Single Sign-On (SSO) between Grist and Keycloak. However, I am encountering issues, and I could use some assistance in troubleshooting the configuration.

Key Points:

I have obtained the SAML metadata from Keycloak, which includes the necessary information for configuring Grist.

When attempting to log in to Grist, I encounter the error: "SAML Assertion signature check failed! (checked 1 certificate(s))."

I have verified the system clocks on both Keycloak and Grist servers to ensure they are synchronized.

I have pasted the relevant sections of the Keycloak SAML metadata, and I don't see any settings in Grist's "Identity Providers" tab.

There is no option to set "Login with SAML" in the realm settings under the "Login" tab in Keycloak.

Request for Help:

Can someone guide me on the correct steps to configure Grist with the Keycloak SAML metadata?
Are there specific settings in Grist that I might be missing?
How can I troubleshoot and resolve the "SAML Assertion signature check failed" error?
I appreciate any insights or advice from the community. Thank you!

from grist-core.

dsagal avatar dsagal commented on June 23, 2024

I found a few items to look into here: Clever/saml2#106. It's not very recent, but maybe something there could help?

from grist-core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.