New plugin type: LoginPlugin

I would like to implement login via external identity providers (OpenID, SAML). For this I would like to propose a new plugin type: LoginPlugin.

  1. Patch the login/ view to check for plugins claiming the login, using .will_handle_login() and .on_login_render().
  2. From there, continue with a custom UserManager and UIPlugin (could be the parent of UIPlugin).

This is a bit of work and requires changes to the core. It's not a breaking change.

I would volunteer to provide the code, but would like to ask for opinions on the forum first, as suggested in the contribution guidelines.

There have been others that have wanted to achieve stuff like this with the login before. Pretty sure they were able to achieve their goal though with the existing infrastructure. I'll see if I can dig up that conversation from Discord. I know others have integrated LDAP/AD authentication too, so maybe similar stuff could be done for OpenID/SAML configs.

Found the discussion in the dev-plugins channel from back in April. Here's the plugin he did for OAuth2.

Thanks for the links, but...

  • I'm not talking about MFA. MFA is not an IDP. Of course IPDs can enforce MFA, but that is irrelevant here. Also, I can't see how the MFA plugin relates to OAuth2.
  • LDAP/AD are fundamentally different things from OpenID/SAML, so the implementations are also quite different.

I know there's OctoPrint-OAuth2. I took a good look at it (I classify it as won't fix) and that a LoginPlugin would provide a good solution for OpenID, SAML, Header-based authentication with an external auth-proxy etc.

this is built into OctoPrint you just have to set everything up correctly in config.yaml I think. I know I've done it with user based certs for passing login information through. All the relevant bits are in here.

I agree though, having something like you describe as a mixin might make sense because you may want to have additional fields on login, etc.

No, it's partly built into OctoPrint. I could somehow bend any auth proxy to make OctoPrint think someone is logging in with Basic Auth. I was thinking of a possible generic implementation of header-based auth, not just Basic Auth. IPD also provides information about user roles and user groups that can be applied to OctoPrint, and things like single sign-out are possible, etc. I had more in mind than just "login".

There's no need for additional fields on the login page. All that is needed is for the plugin to take control of /login to apply the necessary redirects and provide custom templates.

Anyway, I'm going to provide a working prototype and we'll see from there. I'll keep you posted here.

I don't think this should be too invasive to the core code, seeing as a lot of bits are mostly there already. Not sure I see a real problem with it.

Seems like it could be reasonable & simple, effectively extending UIPlugin method to the login route, rather than just main index as it is now.

It is, in a way, possible to override the login page, by being a UI plugin and serving a login page at / - but it's not a proper solution (the implementation involves telling OctoPrint not to check for user permissions - then you check them yourself and handle user login however you want to. It could definitely be tidied up into an actual solution, and not just my thoughts of hacking your way around the problem).

Back in the day, before user login was mandatory for OctoPrint, the login page used to be implemented with a 'ForceLogin plugin' that was actually bundled with OctoPrint. Using the UI plugin mixin to show a login page instead of the UI as I put above. It's similar, but the actual login mechanism was still the built in one we have today, made mandatory.

We may wish to make it clear to users & particularly security researchers that a mechanism for plugins to take over the login handling for OctoPrint does not constitute a security vulnerability - we've had a lot of reports in the past as people think that OctoPrint installs should be bulletproof, even from it's own users shooting themselves in the foot.

The problem I see is that modifying or extending UIPlugin creates a new behaviour and requires proper handling of /login in all plugins for something that wasn't there before, which I would classify as a major breaking change.

Creating a slim child LoginPlugin based on UIPlugin also clarifies the nature of the plugin. I don't see SSO as a UI feature, but something that needs to be done with the UI because of the way OctoPrint is designed.

Only a LoginPlugin would be allowed to override /login, effectively delegating the login process to an external identity and access management system, which is a fairly standard case.