Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authentication in Tide #99

Open
bIgBV opened this issue Nov 30, 2018 · 15 comments
Open

Authentication in Tide #99

bIgBV opened this issue Nov 30, 2018 · 15 comments
Labels
design Open design question
Milestone

Comments

@bIgBV
Copy link
Contributor

bIgBV commented Nov 30, 2018

Currently we don't have a story for authentication in Tide. I hoped that this issue would help start some discussion around the topic. A few questions that come to mind:

  • How much support do we want to provide? Something as involved as Django and Rails? Or something more lightweight like Flask?
  • It most likely will be a Middleware, but is this the best approach?
  • How will it hook into configuration? As discussed in Add configuration (for extractors and middleware) #5 per route configuration could change the way authentication would work for that route.
@bIgBV bIgBV added the design Open design question label Nov 30, 2018
@petejodo
Copy link
Collaborator

petejodo commented Jan 9, 2019

New here and rust in general but interested in tide. Anyway, I guess your first question is asking whether Tide just wants to support sessions, which I presume would be built on top of cookies, or provide some full authentication on top of sessions like Django. Another question is whether to support other authentication strategies such as a token-based one.

Personally I find myself getting confused when reading django authentication documentation. There's too many different parts to it that it feels overwhelming just to get something working. I think providing something barebones/lightweight that can be further built upon would be the goal to strive for (however possible that actually is).

About approaches, another one other than Middleware is doing how Rocket does it with request guards where a struct User can implement FromRequest which is where it makes the db request or whatever is needed and then all the handler needs to do is just have User as a parameter.

@bIgBV
Copy link
Contributor Author

bIgBV commented Jan 9, 2019

Personally I find myself getting confused when reading django authentication documentation. There's too many different parts to it that it feels overwhelming just to get something working. I think providing something barebones/lightweight that can be further built upon would be the goal to strive for (however possible that actually is).

To be fair, it is a very complete solution. By providing sessions by default, session management becomes extremely easy. You can hook into external stores for sessions simply thorough configuration and everything just works. With something like flask on the other hand you have to maintain your own code for this. I haven't used Rocket, but I am guessing it is similar to Flask in this regard.

@mmrath
Copy link
Contributor

mmrath commented Jan 10, 2019

About approaches, another one other than Middleware is doing how Rocket does it with request guards where a struct User can implement FromRequest which is where it makes the db request or whatever is needed and then all the handler needs to do is just have User as a parameter.

This is something I dislike. If this is required, it can be supported with a extractor but auth is something a Middleware can handle very well. For rocket I have raised an issue to support middleware like functionality specifically for authentication(rwf2/Rocket#749).

@mmrath
Copy link
Contributor

mmrath commented Jan 10, 2019

I think authentication support implementation should be delayed until the framework is more stable. most of the authentication related functionality can be written on top of tide initially to try different approaches. And possibly merge once there is some good consensus. There is also authorisation functionality that need to be thought of when designing authentication.

@yoshuawuyts
Copy link
Member

I think authentication support implementation should be delayed until the framework is more stable. most of the authentication related functionality can be written on top of tide initially to try different approaches.

Perhaps a useful challenge would be for people to try and develop a password/email cookie authentication flow, in separate repos.

I think having some simple, tangible examples of what authentication flows can look like with Tide might help inform the design space, and allow us direct the discussions a bit more.

@markbahnman
Copy link

I've been toying around with tide for a basic REST api and I think most of the pieces for a basic auth flow are already here. Use middleware to authenticate the request and stuff the session data into the request extension, use a Computed extractor in a handler to make that data accessible to your function.

@petejodo
Copy link
Collaborator

I was thinking something along the same lines but extract the session handling into a separate AuthenticationStrategy trait which would handle the session stuff or another could use JWT or OAuth. Taking it further, there could be another trait, AuthenticationHandler, that the user implements which would be the actual code that verifies against their specific database or whatever.

So you have AuthenticationMiddleware<AuthenticationStrategy, AuthenticationHandler> and the user would do something like

let auth_middleware: AuthenticationMiddleware<auth::SessionStrategry, MyAuthHandler> = AuthenticationMiddleware::new(
    auth::SessionStrategy::new(/* ... */),
    MyAuthHandler,
);

struct MyAuthHandler;

impl AuthenticationHandler for MyAuthHandler {
    verify_user(/* ... */) -> Result<NotSure, AuthError> {
        /* ... */
    }
}

I'm kinda just spitballing so I haven't really thought of what the actual implementation would look like though

@yoshuawuyts
Copy link
Member

Tide 0.0.1 has been released, so if people would want to start on sketching examples it should be a bit more convenient now!

@tomhoule
Copy link

I already mentioned it in the session design issue, and it's not a full authentication solution, but I just published a rough prototype for a session management middleware in this repo. It's only cookie-based, so not as generic as what @petejodo suggested. Any form of feedback is greatly appreciated.

@bIgBV bIgBV added this to the Sprint 2 milestone May 9, 2019
@bIgBV
Copy link
Contributor Author

bIgBV commented May 20, 2019

@prasannavl @fairingrey @Nemo157 the repo linked in the comment above contains a really well thought out authentication scheme including sessions for tide. I we should look into bringing this into the tide ecosystem. There can be further discussion as to whether or not we want to include this in tide-core or not, but I feel that tide requires a solid sessions and authentication story.

@yoshuawuyts
Copy link
Member

It feels we could probably put out an RFC for the design in this so we can discuss the API before implementing it.

We've done an RFC before in https://github.com/rustasync/tide/blob/master/rfcs/001-app-new.md, but modeling it after https://github.com/rustwasm/gloo/blob/master/rfcs/001-mid-level-file-api.md is probably better.

@bIgBV would you want to start the process of drafting an RFC for authentication?

@bIgBV
Copy link
Contributor Author

bIgBV commented May 23, 2019

@yoshuawuyts I'll open an RFC by tomorrow.

@prasannavl
Copy link
Contributor

prasannavl commented May 24, 2019

@bIgBV - This is great to think about! Personally I think both auth and sessions should purely implemented as middleware with some extensions as helpers, and other than the fact that auth optionally requires some kind of session backend in specific cases, I think it'd be great if both are approached are two completely independent items.

The way I see it, is similar to how compression is handled. Do the heavy lifting in the something say a generic auth/webauth [not to be confused with webauthn] crate outside of tide similar to async-compression. And then use a middleware and/or extensions that ties that into tide. Auth is likely small enough on a trait level (probably just one or two methods generically abstracted), and large enough on the variety, complication and security aspect of the implementations that it's probably best for both tide and the rust community in general if it works across actix, tower, and tide.

Regardless of how great an auth story we provide with tide, I think something to be careful about is to be able to keep it optional and be swappable as opposed to forcing an auth story down the throat, regardless of how good, integrated or secure it feels - I've seen weird, custom requirements for auth so often that it can almost never be satisfied on the framework level.

Personally, as far as default story goes, I like how .NET Core does it - https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.2&tabs=visual-studio - they key here is in focusing on the common interface for things like Identity, TokenProvider, etc and not auth itself directly - and then let auth just be implementations over them.

Again, we've also been talking "auth" - but not looked into "authentication" and "authorization" specifically as well - both are again different things that has to dealt with for a complete auth story.

@bIgBV
Copy link
Contributor Author

bIgBV commented May 24, 2019

@prasannavl those are all some great points. The initial proposal that I came up with was something very similar to what you are proposing here. Having a trait definition in Tide and each authentication backend having its own adaptor fitting to this trait. I did not fleshed out the details, but having this separation of concerns would allow us to be flexible in the kind of schemes that could be supported.

I agree with your idea of having a separate auth/webauth crate which provides common authentication schemes across different identity providers. Plus given the security implications of an improperly written auth backend, I think its better to have a common vetted library providing the functionality.

And yes, authorization is something which we will have to consider as well. In the web frameworks I have used, authorization is generally modeled as the next step after authentication with the code generally residing in the same module. So we will have to consider if we want to integrate authentication and authorization into the same library or keep them as separate libraries.

@manifest
Copy link

Just a few thoughts on that matter.

I'm on the same page with @prasannavl. It makes perfect sense to separate authentication and authorization for the following reasons:

  • They solve different tasks: identification of a subject and managing access to object accordingly
  • Authn is well defined by standards when authz highly depends on business logic of an application
  • There are lots of IaaS that may only be used if those two are separated

Authn and sessions shouldn't be mixed neither. That only may simplify development of basic applications, but for high load web services we usually don't want to be dependent on any global state and prefer to have an implementation of authn as light as possible.

For our web services we use tower-web with:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Open design question
Projects
None yet
Development

No branches or pull requests

8 participants