qpixel
qpixel copied to clipboard
Add SAML support
This PR adds SAML support.
Design questions/decisions
- This PR adds the SsoProfile model which stores the information from SAML in the case it exists. At the moment this is a single field, so it could also be added to the user model instead. However, for complex scenarios additional fields may need to be added, where it would make sense to have these separated into their own model.
- I've added support for 2FA in combination with SSO login. However, the SSO service may already request the user for 2FA. In the general case, I don't expect users to use the application 2FA in conjunction with the SSO, but the option is there.
- I expose the first_factor class variable from SessionsController such that I can access it from the SamlSessionsController. Ideally I would let the SamlSessionsController extend the SessionsController, but unfortunately ruby does not have multiple inheritance.
UI
- The SSO Sign In button either replaces the Sign Up + Sign In buttons, or is added in conjunction in case MixedSignIn is enabled.
- Add a notice for the sign-in and registration page to sign in with SSO (SSO + MixedSignIn only)
Routes
- This adds devise routes under
/users/saml/.... These routes are only active if the site settingSsoSignInis enabled (they dynamically become active or inactive). This means that no additional endpoints (security risks) are present whenever SsoSignIn is disabled.
Database migration
- The database migration adds the
sso_profilestable(saml_identifier), but does not alter any existing tables. No existing tables or data is modified.
Configuration
- Two new global site settings are added:
- SsoSignIn -> controls whether sign in with SSO is enabled
- MixedSignIn -> if sso is enabled, normal sign in becomes unavailable unless if mixed sign in is enabled. (ideally we would have a setting where you can choose between 3 options (Normal, SSO, Mixed), but this is not currently possible).
- The added configuration should suit both basic and more complex scenarios. The comments in the configuration already provide a reasonable explanation on how to configure it (
config/initializers/devise.rbat the bottom and theconfig/attribute-map.yml).
Documentation
Added as wiki page: https://github.com/codidact/qpixel/wiki/Setting-up-SAML---Single-Sign-On
Tasks to do
- [x] Integration with 2FA
- [ ] Test (manually at least) whether 2FA + SSO Sign In works
- [x] Disable normal sign_in/register/confirm routes if SSO sign in is enabled and mixed sign in is not.
- [ ] Add tests for checking sign in options when SsoSignIn is enabled / MixedSignIn is enabled.
- [x] Add tutorial somewhere (docs repo? wiki?)
- [ ] Figure out something for impersonation password request (sign out?)
Closes #825
@cellio Do you have a suggestion for where I can add the documentation for this? I seem to be able to add wiki pages, but the wiki currently says that there is no wiki and that all documentation is in the codidact/docs repo (which contains outdated information?). I can also add it as a markdown file, but I think it is nicer to keep the documentation more separate from the code base.
@Taeir I see that the installation guide is in this repo (https://github.com/codidact/qpixel/blob/develop/INSTALLATION.md), so maybe we should put the SAML doc there too? Pinging @ArtOfCode- for possibly a better answer. (This is my first OS project so I'm not as familiar with the norms as you and Art are.)
Another possibility (deferring to Art) would be to use this repo's wiki, replacing that landing page that says "go use the now-out-of-date docs wiki" with something current.
Wiki makes sense to me. We could also copy the readme/installation guide there as well.
I updated the landing page on this repo's wiki. I don't currently know how to grant write access and I'll be going offline soon until Saturday night; @ArtOfCode- if you're around can you take care of that? Thanks.
@Taeir Re testing, we have a dev system we can probably make a backup of + push this PR to when ready. Just have some thoughts for you in the meantime:
- What kind of IDP system are you hoping to target SAML to? If its something like Shibboleth/Okta/OneLogin, we may as well as provide example configs/screenshots to make the setup a little more hassle free.
- SAML IDPs can be just a passthrough to LDAP systems. Should we recommend to users that want to keep using LDAP to set up a SAML service instead and forego direct LDAP integration in QPixel?
- (my opinion only for this last one) It's a bad idea to "enforce" 2fa if SAML is the only "active" login method. If it uses a "native" or "mixed" (can log in "natively" or via SAML) mode, then fine, but the intent of an SSO system is to generally outsource all the "auth bits" as well. Feel free to gate this enforcement component behind a setting (probably default the "service side 2fa" to off) if this is something that you really want to keep.
@sau226
- What kind of IDP system are you hoping to target SAML to? If its something like Shibboleth/Okta/OneLogin, we may as well as provide example configs/screenshots to make the setup a little more hassle free.
We use it with our institution's SAML system (Delft University of Technology), which is probably a simpleSamlPHP instance with custom settings. We also have a test SAML server with the same configuration but mock accounts which we use for the development of our applications to test SAML integrations. We are already using QPixel with SAML in production, but this PR polishes up the code and makes it more configurable to other scenarios + provides instructions. I agree that it would be good to provide examples of linking with Okta or OneLogin, as those are probably a more common use case.
- SAML IDPs can be just a passthrough to LDAP systems. Should we recommend to users that want to keep using LDAP to set up a SAML service instead and forego direct LDAP integration in QPixel?
Are there currently institutions you are aware of that use LDAP login with QPixel? My institution indeed has the SAML IDP as a passthrough to their LDAP directory. A direct link to LDAP in QPixel is possible as well, but less "trustworthy"/convenient since you don't get the organizational login screen, autofill credentials, additional 2FA options, and the only-sign-in-once experience. Adding LDAP login support to QPixel is possible as well, but more of a hassle due to the additional views required to make that work with mixed sign in (usually it applies the ldap login on the normal sign in page). I have not worked before with the devise_ldap_authenticatable gem, but I suspect it to be somewhat similar.
- (my opinion only for this last one) It's a bad idea to "enforce" 2fa if SAML is the only "active" login method. If it uses a "native" or "mixed" (can log in "natively" or via SAML) mode, then fine, but the intent of an SSO system is to generally outsource all the "auth bits" as well. Feel free to gate this enforcement component behind a setting (probably default the "service side 2fa" to off) if this is something that you really want to keep.
With enforcement you mean for mod+? I think all other users have an opt in to use 2FA. If you use mixed sign in, I don't think it makes sense to disable 2FA site wide, and the question is whether this makes sense as a separate setting. Instead, we could:
- Don't enforce 2FA for mods if they are SAML users, require 2FA with SAML if users enabled it for their accounts.
- Disable 2FA for SAML sign ins and list this with the enforcement of 2FA settings. Normal 2FA will apply when signing in through a different method.
The second option would be easy to add, as it only requires removing some logic from the saml_sessions_controller.
@sau226
Re testing, we have a dev system we can probably make a backup of + push this PR to when ready. Just have some thoughts for you in the meantime:
I don't really understand what you mean by this. You mean a staging setup for testing purposes?
Added some new restrictions regarding 2FA:
- (By default) 2FA is not checked for SSO users even if enabled
- (By default) SSO users cannot enable 2FA in the UI
- (By default) 2FA is not enforced for global administrators when they sign in using SSO, even if this setting is enabled
There is a global site setting to configure whether SSO users can use 2FA. If this is set, it behaves like for normal sign in.
Added some new restrictions:
- SSO users cannot change their email or password (as these are provided by the SSO service)
- SSO users cannot sign in through normal authentication even when mixed authentication is allowed.
- SSO users can now disconnect their account from SSO if the server supports mixed sign in (if the global site setting for it is enabled, it is not by default)
@ArtOfCode- This is ready for re-review.