volatiletech / authboss

The boss of http auth.
MIT License
3.81k stars 207 forks source link

Hydra login, consent, logout flow module #258

Closed ashtonian closed 3 years ago

ashtonian commented 4 years ago

I've created a module to integrate authboss and hydra. This allows an authboss backed api to provide login/consent flow for the hydra oauth2 flow. The module adds /login,/consent, and /logout api calls. I'm not that familiar with authboss yet, and wondering if you had any initial feedback. The test folder is currently a mess and not really testing anything properly. Currently planning to address that and improve documentation next.

I had a couple of initial questions:

aarondl commented 4 years ago

One big question I have is: What is hydra and why is this concerned with it at all? Isn't it just some OAuth2 server? In which case should this not be more concerned with OAuth2? Also in which case could this not use Authboss's existing OAuth2 API to connect with it?

If not - a very specific (hydra) module like this probably belongs outside the main repository since it's unlikely many people are going to be able to use it and it brings with it considerable heft (reliance on a specific server + database etc. none of which currently are required for anything in this package).

As for your questions:

whats the difference between using the authboss redirector and http.redirect()?

Everything in Authboss is a small interface where possible because the ability to customize how things are handled is key in a "framework" like this. For example when people are using Authboss in API mode, a common change to the redirector is to have it just return 200 OK with a body that looks like: {"redirect": "/some/page"}. In a SPA designed front-end an http.Redirect breaks the application.

all of the POST /login code, and half the POST /logout are copied from those respective modules, I was wondering if you had any thoughts on re-using that code or not. I've thought about importing the modules directly and attempting to just wrap the function calls required without calling the Init() function but wondered what your thoughts were.

I think it's generally fine to just import and re-use directly if it weren't for our prolific use of init(). If it's true that the auth module will never be used alongside this one then it's fine.

The newer modules do not use init() but unfortunately until we rev 3 authboss we're stuck with the ones we have.

also any preferences or guidelines for events and errors?

Not really. Everything in Authboss returns an error so that we can easily handle them at a global level. You should just be able to return a generic errors.New() and it should kinda work.

Keep in mind your application owns the router, so you can pass specific errors and handle them at a level higher than authboss too.

For eventing, I'm not sure what generic advice I could give. Any more specific questions about the eventing?

ashtonian commented 4 years ago

Thanks for the feedback!

One big question I have is: What is hydra and why is this concerned with it at all? Isn't it just some OAuth2 server? In which case should this not be more concerned with OAuth2? Also in which case could this not use Authboss's existing OAuth2 API to connect with it?

Hydra is an server implementation of OAuth2/OpenID and yes it can be used with the OAuth2 module so that authboss can use it as an provider. Hydra however is very lightweight and only implements the very outer negotiation layer of OAuth2/OpenID and doesn't implement user management or related concepts of any kind. It requires what they call an 'Identity' server that essentially handles all user state including authentication info like email/password. It does this technically via redirects and callbacks, and in turn as a implementor of Hydra you are required to implement what they call a 'login-consent-flow' which is essentially what this new module is. Its a series of endpoints(POST/GET Login|Consent|Logout) you configure hydra to be aware of so that when it gets an OAuth2 request it knows where to redirect the login and related info to. Pairing Hydra with Authboss allows a developer to provide their OWN OAuth2/OpenID server where the users are managed and authenticated still through authboss interface. I believe with some additional work you would be able to use this in conjunction with the OAuth2 provider modules to allow for a pretty robust auth solution where you were always using OAuth2 Tokens via hydra or others all while authboss manages the user state.

Here is what their docs say about this.

Flexible User Management
One of ORY Hydra's biggest advantages is that unlike other OAuth 2.0 implementations, it implements the OAuth and OpenID Connect standard without forcing you to use a "Hydra User Management" (login, logout, profile management, registration), a particular template engine, or a predefined front-end.

This allows you to implement user management and login your way, in your technology stack, with authentication mechanisms required by your use case (token-based 2FA, SMS 2FA, etc). You can of course use existing solutions like authboss or auth0.com. It provides you all the benefits of OAuth 2.0 and OpenID Connect while being minimally invasive to your your business logic and technology stack.

In summary Hydra acts as a drop on OAuth2/OpenID server around Authboss allowing users to be their own OAuth2/OpenID provider.

If not - a very specific (hydra) module like this probably belongs outside the main repository since it's unlikely many people are going to be able to use it and it brings with it considerable heft (reliance on a specific server + database etc. none of which currently are required for anything in this package).

I understand that and would be totally cool with doing that. Part of the initial motivation for internal repo is I think there were other packages like defaults that I wanted to update to support the form submission and resolve conflicts with the existing Auth module. As for the popularity you may be right, however Authboss is specifically referenced in the Hydra repo readme as a potential for an identity service, and their stack is growing quite the community.

I think it's generally fine to just import and re-use directly if it weren't for our prolific use of init(). If it's true that the auth module will never be used alongside this one then it's fine.

The newer modules do not use init() but unfortunately until we rev 3 authboss we're stuck with the ones we have.

I don't want to make that assertion, I think I'll add some comments to make it pretty clear what was sourced from where and address this after rev 3. Worst case I could always submit a PR to refactor those modules abstracting the functions needed. We haven't repeated more than twice yet... ha.

Keep in mind your application owns the router, so you can pass specific errors and handle them at a level higher than authboss too.

For eventing, I'm not sure what generic advice I could give. Any more specific questions about the eventing?

I think the event system is simpler than I thought after looking more in depth at the other modules I think I can make a pretty good attempt.

aarondl commented 4 years ago

Hi @Ashtonian. I haven't replied since I didn't know if there was much else to say currently. I do think we should keep this in a separate repository. I'd hope that you can create that repository and put a link to it here. I can also help do code reviews on it if you'd like, we can keep the conversation going here or if you prefer you can close this PR and create an issue in the other repo and tag me.