horizon
horizon copied to clipboard
[Proposal] Support for OpenID Connect (OIDC) Authentication (obliterating own user management)
I would like to propose support for a generic OpenID Connect authentication adapter. OpenID Connect is a standardized protocol and simply an authentication layer on top of OAuth 2.0.
It is already supported by an increasing number of public identity providers, including Google, Microsoft Accounts, Microsoft Azure AD, Salesforce, Paypal, Amazon Cognito, Auth0 and many more.
Both clients and servers are readily available. An overview can be found at http://openid.net/developers/libraries/.
Configuring an OpenID Connect client, even for a completely new identity provider is as easy as providing client key and secret, as well as the path to the providers configuration endpoint defined in the Openid Connect spec.
As the protocol also specifies a standardized userinfo endpoint fixing https://github.com/rethinkdb/horizon/issues/841, https://github.com/rethinkdb/horizon/issues/563 and https://github.com/rethinkdb/horizon/issues/216 would be trivial and most likely part of the implementation.
This proposal also alleviates the need to
- implement password auth https://github.com/rethinkdb/horizon/issues/176
- Add a user-create command https://github.com/rethinkdb/horizon/issues/550
- make Horizon its own Oauth provider https://github.com/rethinkdb/horizon/issues/615
- support multiple oauth providers simultaneously https://github.com/rethinkdb/horizon/issues/682 (OpenID Connect also standardizes Identity Federation/"Social login")
Since the protocol is standardized, it half-way fixes https://github.com/rethinkdb/horizon/issues/428 and makes adding new providers (https://github.com/rethinkdb/horizon/issues/271) trivial as this just means providing a new configuration for the OIDC adapter.
Since the redirect URL is just part of the adapter configuration it also fixes https://github.com/rethinkdb/horizon/issues/230.
I am generally a proponent of the Unix philosophy of doing one thing and doing it well. Since even setting up your one's own OIDC provider can be as easy as starting a docker container or signing up for Cognito/Auth0 I would like to lobby for keeping the user management facilities within the core of horizon at a minimum and move towards OIDC support instead.
Looking forward to your feedback!
Update - 03/22/17 There are two general ways to implement this:
- Horizon as Relying Party (OpenID Connect Client) Implement Auth Code Flow in Horizon, e.g. using https://github.com/panva/node-openid-client. This is analog to the current OAuth2 implementation and could also extend that. Requires Horizon to handle its own user sessions (as currently done via issuing signed JWT tokens).
- Horizon as Resource Provider (API Server/Backend Node) The Client (Mobile/Single-Page/Web-Application) acquires an Access/ID Token from an OpenID Connect Identity Provider on its own and provides either to Horizon to authenticate there on behalf of the user. Option a): Present ID Token - Only a good idea when the ID token is shortlived (i.e. 5 minutes) just like a typical access token. Allows Horizon to derive all relevant user details directly from the ID token and is thus extremely scalable. Cf. https://developers.google.com/identity/sign-in/web/backend-auth Option b): Present Access Token - In order to verify the user identity, Horizon needs to pass on the access token to the Identity Provider's userinfo endpoint (specified in OIDC spec) and process the results. This adds latency to the authentication and load to the Identity Provider.
I have implemented Option 2a) (best for my usecase) in a private fork and would be happy to discuss.
I totally agree with keeping the user management at a minimum, from my use case I see that auto reconnects and easier server side validation are far more important at this stage. I say this because I am embedding horizon in my application so adding complex logging is just a usual Express hack, but I don't believe that this would be the case if I was serving my app with horizon (via hz cli). So it is very important to use an authentication mechanism that is suitable for the general use case, and for those who want to try something more complex or different (the remaining 10 %) embed horizon and add your thing via some rest api.
I have implemented OIDC ID Token auth. See above for details.