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

OAuth-based Authentication #6

Open
chillu opened this issue Oct 30, 2016 · 10 comments
Open

OAuth-based Authentication #6

chillu opened this issue Oct 30, 2016 · 10 comments

Comments

@chillu
Copy link
Member

chillu commented Oct 30, 2016

Session-based authentication relies on a manual mechanism for signing in (CMS login form). While we can already use programmatic authentication with Basic Auth over SSL, it's not very friendly to typical third party integrations. Implement an OAuth provider to make this more flexible, e.g. with http://oauth2.thephpleague.com/. It's unclear which flow we'd use (since we don't want any further user action beyond logging in to the session-based CMS).

Related:
https://medium.com/the-graphqlhub/graphql-and-authentication-b73aed34bbeb#.ys9c7gc32
https://dev-blog.apollodata.com/a-guide-to-authentication-in-graphql-e002a4039d1
https://dev-blog.apollodata.com/auth-in-graphql-part-2-c6441bcc4302
http://graphql.org/graphql-js/authentication-and-express-middleware/

@robbieaverill
Copy link
Contributor

@chillu I'm happy to help out with this if you need some extra resource.

Re: the two auth flows - perhaps you could distinguish the authentication method from a request header. Either match the OAuth header or a custom SS session header.

@chillu
Copy link
Member Author

chillu commented Dec 18, 2016

@robbieaverill Thanks for your offer, we can absolutely use the help! :)

At the moment, the GraphiQL browser with the SilverStripe Content API will return empty results filtered by canView(). A quick fix for this would be allowing basic auth passed in through HTTP headers - which is still a bit finnicky since you need to base64 encode them ready for the HTTP header (can't set user and password separately in GraphiQL). That's more of a missing feature in GraphiQL though, and basic auth is good enough for development work. Plus it already works out of the box in SilverStripe.

I don't think we need a viewer root node, but maybe I haven't understood the concept completely :)

Regarding an OAuth 2.0 server, this would implicitly add OAuth support to SS core, which is a fairly large security surface - and hence would need some form of RFC. Ideally we'd avoid running an XHR from the client for this, but rather auto-generate a token on the server, stored against the member. I'd rather not reuse the "remember me" token for this. It would have to be removed on logout, so a simple 1:1 relationship with sessions. And should have an expiry date which matches the PHP session. A separate module might also allow multiple API keys (and a UI to manage them), but that's out of scope for now.

The Oauth 2.0 server implementation should be a separate module, which can be applied through the SilverStripe\Control\RequestFilter middleware - so the GraphQL module should only need some configuration to apply it to the /graphql endpoint.

Apollo authorisation is easy through middleware.

Note that there's https://github.com/bigfork/silverstripe-oauth, which is an OAuth client, not server.

Does that give you enough to get started Robbie? This is really about "OAuth server in SS" more than in silverstripe/graphql.

@chillu
Copy link
Member Author

chillu commented Dec 18, 2016

As a simple start, you could just describe how to add basic auth to GraphiQL in the README?

@robbieaverill
Copy link
Contributor

Hey @chillu - sounds good, just a couple of things to clarify:

So the context for this is authenticating frontend calls to the GraphQL endpoints from within a SilverStripe site - i.e. a decoupled web app, rather than external applications accessing a SilverStripe GraphQL endpoint?

Ideally we'd avoid running an XHR from the client for this, but rather auto-generate a token on the server, stored against the member.

You're talking about a sort of pre/automatically authorized OAuth token set which the frontend can use to communicate with the backend? Seems sensible to me. It could also be augmented at a later date if required to provide full OAuth support for SilverStripe.

As a simple start, you could just describe how to add basic auth to GraphiQL in the README?

I agree - this would be worth doing to start with to establish the authentication integration process and ensure that it works. Then chuck something a bit meatier over the top.


I assume there's not a huge rush for this, but I'll work on this a little over the break and will aim to have it complete when we get back in.

Cheers!

@chillu
Copy link
Member Author

chillu commented Dec 22, 2016

So the context for this is authenticating frontend calls to the GraphQL endpoints from within a SilverStripe site - i.e. a decoupled web app, rather than external applications accessing a SilverStripe GraphQL endpoint?

Both. Dev will want to test their queries in external tools like GraphiQL.

You're talking about a sort of pre/automatically authorized OAuth token set which the frontend can use to communicate with the backend?

Yes, so for the SS4-internal authentication we'd only use one particular flow (auto generated token). I wouldn't start the OAuth implementation from scratch though, even for this relatively simple use case - I hope that the phpleague module would work for us, but needs more research since it'll add yet another core dependency (amount of code pulled in, amount of libraries)

I assume there's not a huge rush for this, but I'll work on this a little over the break and will aim to have it complete when we get back in.

Yep, we have a working solution at the moment (session-based), and you can use dev/graphiql built into the silverstripe/graphql module for running queries.

@robbieaverill
Copy link
Contributor

Status

#44 introduces an AuthenticatorInterface and a BasicAuthAuthenticator which can be enabled via YAML configuration to authenticate via the native SS BasicAuth::requireLogin method, and provide a Member to GraphQL for use within query contexts.

The interface is simple and easy enough to add custom authenticators to (dev only example).

I have made a start on implementing the PHP League OAuth2 server, however it requires PSR-7 compatible request and response interfaces, which SilverStripe doesn't have at the moment (related: silverstripe/silverstripe-framework#4484, mailing list discussion).

I spent a bit of time working on a HTTPResponse adapter that implements the appropriate PSR-7 interfaces, but it is a big job and I'm not sure I'll have time to finish it in a reasonable timeframe outside of work commitments.

The actual implementation of the OAuth2 server shouldn't take too long since it comes with traits that provide most of the standard functionality - it's mostly just a case of connecting the interfaces repositories and entities to the appropriate SilverStripe DataObjects.

I'll keep the work I've done somewhere local and can chip away at it gradually, but perhaps we should roll-our-own OAuth based token authenticator in the meantime...?

cc @chillu / @sminnee

@sminnee
Copy link
Member

sminnee commented Jan 8, 2017

💯 ❤️ for a PSR-7 bridge

@robbieaverill
Copy link
Contributor

I've put together a simple PSR-7 adapter set, so the OAuth implementation seems to be coming along a bit better now.

@sminnee's API key module might be worth upgrading for SS4 and implementing in the meantime too.

@robbieaverill
Copy link
Contributor

robbieaverill commented Jan 20, 2017

sminnee/silverstripe-apikey#8 has a compatible authenticator added for GraphQL.

Merged: this adds a lightweight option for token based authentication in this GraphQL module until OAuth is available. cc @PapaBearNZ

unclecheese pushed a commit to open-sausages/silverstripe-graphql that referenced this issue Jan 9, 2018
@maxime-rainville
Copy link
Contributor

Looks like other people already had a go at doing an integration with PHP League OAuth2 package https://github.com/advanced-learning/silverstripe-oauth2-server

I had a got at getting it running locally last night, but it's targeted to GraphQL 1, so it might need a bit of refactor to work with our latest version.

unclecheese pushed a commit to unclecheese/silverstripe-graphql that referenced this issue Jan 27, 2021
…-this

Re-instate the insert oembed function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants