Problem/Motivation
Drupal 7 only supported cookie authentication. Drupal 8, because it wants to be API-first, has the concept of authentication providers. The only one included with Drupal core is \Drupal\basic_auth\Authentication\Provider\BasicAuth, in the basic_auth module.
This means that when you use the REST module in core (or the JSON API or GraphQL modules in contrib), you can only use:
- Cookie authentication
- HTTP Basic authentication
- … and no authentication (anonymous)
Neither of these are considered best practices when interacting with REST APIs. In fact, all of them are terrible choices, and are heavily looked down upon.
The vast majority of these APIs use OAuth 2.0. Specifically, OAuth 2 bearer token.
Proposed resolution
As part of the API-first initiative (#2757967: API-first initiative), we'd like to propose to add OAuth2 to Drupal 8.3 core as an experimental module. This should come as no surprise because #2757967 has mentioned it since being published on June 29.
@e0ipso is the maintainer of the https://www.drupal.org/project/simple_oauth module, which implements OAuth2 bearer token. Unfortunately, it's all Drupal-specific code. Even though the OAuth 2.0 spec is notoriously difficult to implement correctly/completely. So, bringing this module to Drupal 8 core would've had quite a big associated risk: we'd be taking on building and maintaining our own implementation of an OAuth 2 server.
A much lower risk would be to use the PHP library that is the most widely installed/depended upon library in the entire PHP ecosystem to build an OAuth 2 server: thephpleague/oauth2-server. We proposed he rewrite his module on top of that. e0ipso started doing so, and in fact finished doing so a few days ago: https://www.drupal.org/project/simple_oauth/releases/8.x-2.0-alpha1 is the first release of the 8.x-2.x branch.
Even though this branch of the module has only existed for a very short time, we think it's appropriate to include it in Drupal 8.3:
- including the 8.x-1.x branch would be signing us up for maintenance of the implementation of a complex spec: dangerous
- we're building on top of a mature, broadly used, battle-hardened implementation:
thephpleague/oauth2-serverwith more than one million downloads and extensive test coverage. This library is used for OAuth purposes in popular frameworks like Laravel and Cake PHP 3. The library implements the following RFCs: - not having Oauth2 in core could lead to many more people not using Oauth2 at all, thus being less secure and giving decoupled Drupal a bad reputation
- the library itself has extensive test coverage (and the Drupal module already has functional tests)
- this module would never get as much usage in contrib as it would in core, even if only for discoverability reasons. So only if it's in core, we'll get the massive real-world feedback we need for something like this to mature & graduate to "stable in core"
- There are 4 types of OAuth2 grants — we can decide which grants we want in core and leave the rest for the
oauth2_advancedcontrib module.
Remaining tasks
- Consensus about the principle that we want to add
oauth2authentication to Drupal 8 core as an experimental module. - After that basic consensus: we need to agree on which types of grants make sense for Drupal core to support. (Any grant types we agree don't make sense for core can be supported by a
oauth2_advancedmodule in Drupal 8 contrib.) - After complete consensus:
- Review cycle
- Commit
User interface changes
None.
API changes
None.
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #6 | Which Grant? 2016-12-12 12-04-04.png | 94.95 KB | e0ipso |
Comments
Comment #2
gábor hojtsyIMHO this should be in the ideas queue.
Comment #3
wim leersComment #4
skyredwangI am not questioning anyone's work or decision. I haven't looked OAuth2 for 3 years. Just wondering how OAuth2 solved its own problem:
-- https://hueniverse.com/2012/07/26/oauth-2-0-and-the-road-to-hell/
Comment #5
miklGreat idea, this would go a long way towards establishing Drupal as a serious web service platform. OAuth2 is finicky and hard to get right, so an out of the box solution would be great.
#4: Despite these criticisms, OAuth2 has become the industry standard for web service authentication. There is no successful competing standard, and while not perfect, it's still much, much better than cookies or HTTP Basic Auth.
Thus, adding OAuth2 would be a definite improvement, and I don't think we ought to let perfect be the enemy of good here.
Comment #6
e0ipsoIn regards to #4.
There was quite a reaction after that post (from one prominent OAuth 1 contributor). Although I haven't been following close, I don't seem to recall any security scandals related to the OAuth2 protocol itself in many years after those predictions.
Alex Bible (the author of the OAuth2 library that backs the proposed module) describes Hawk in https://www.alexbilbie.com/2012/11/hawk-a-new-http-authentication-scheme. It's interesting his take on:
Which hints that without Oz, Hawk may be only covering a limited set of use cases. The following diagram explains the use cases that OAuth 2 can cover.
Comment #7
dawehnerIf we talk about MVP maybe its enough to start with supporting just user access token owners, and then maybe bring in the machine one later.
Given then we of course we should really support a user-agent-based app, much better described as (
. On top of that we also want to support a more traditional web app. For user-agent=based apps it seems okay from a MVP point of view to start with just first party support which leaves us with the following two grant systems:
Comment #8
andypostWould be great to update summary why
thephpleague/oauth2-serverconsidered as mature, who are other competitors and how release cycle of this one fits in core release cycleComment #9
e0ipsoComment #10
e0ipso@andypost I updated the issue summary with some more context on why to use this library. This was also recommended by @Crell at DrupalCon Dublin during the API-First hard problems meeting. Quoting from Preston's meeting notes
The other contestant is https://packagist.org/packages/bshaffer/oauth2-server-php. I would rate it at a similar lever as the League's library: +1M downloads, used on the Slim and Yii frameworks, good test coverage and sticking to the FIG recommendations.
I'm unsure if there is a lot of benefit to switch to
bshaffer/oauth2-server-php, but I'm completely certain that if we did it would get the job done. I couldn't find any online post comparing both libraries.Comment #11
e0ipsoThe 3 grants that I think are the most interesting to have in core are:
Comment #12
Crell commentedI've not used either bshaffer's library or the League's library myself, so have no personal experience to offer. However, there are a bunch of add-ons for the League library that talk to various other OAuth services (Facebook, Google, GitHub, Twitter, etc.). That seems potentially useful. Also if the code to use the League's library is already written, well, shipping code wins.
I'm on board with adding OAuth to core via a 3rd party library and bridge code. I am 100% against adding a custom OAuth implementation to core, for the various reasons already given. (Largely the "no, we don't want to maintain that" argument.)
Comment #13
pjcdawkins commentedI have a fair amount of experience with both libraries, and I'd lean towards recommending the League's one, as I have the impression it's easier to work with and more actively maintained.
However, I'd just like to point out the existence of the (very popular in D7) https://www.drupal.org/project/oauth2_server module, which uses bshaffer's library.
Comment #14
Crell commentedA completely unscientific Twitter feedback request suggests both libraries are "good": https://twitter.com/Crell/status/809849007849738240
Comment #15
giorgio79 commentedAs I understand, an oauth server would allow Drupal to become an identity provider for third parties, right? If yes, IMHO Drupal missed the identity bus a long time ago. How about we take care of the other side of the equation? Who fills out email / password fields these days? Lets use Hybridauth in core.
Don't reinvent the wheel :)
Comment #16
e0ipso@giorgio79 the current proposal, as suggested in #11, will leave the 3rd party grants for a contrib module. So that statement is not 100% correct. It will allow users to use their credentials "without having to send them back and forth" between the server and the client. Moreover the two grants that are proposed do not assume a web page to have a person type their LinkedIn/Facebook/… password.
If you look at the diagram at #6 you can see that the OAuth grant that you are thinking of is Authorization code (and maybe Implicit grant). If you are curious about what those grants look like, you can watch videos 8 and 9 of this video series.
Comment #17
hampercm commentedThe intent behind adding OAuth2 here is to improve authentication/authorization for REST and similar APIs, rather than replacing the traditional user login. I definitely think this is an important step for Drupal's API-first Initiative, as OAuth2 support among App frameworks like Ember.js is readily available, and much preferable to the only current option: Basic Auth.
I don't think that adding HybridAuth (which relies on third-party services to authorize access) to core is philosophically on-target, and not really the use case being discussed here.
Comment #18
e0ipso@hampercm I think I understand from your comment that you think it's a good idea to include OAuth2 into core as an experimental module. Please correct me if I'm wrong.
Comment #19
wim leers@giorgio opened #2837115: Enable one click login / registration with hybridatuh to propose for core inclusion. Please keep all discussion about it in that issue.
Comment #20
buddaHaving oAuth2 in core would make the whole authentication area one less thing to think above when using the API services of Drupal 8.
Using an existing library to reduce maintenance gets my vote too.
Comment #21
David Hernández commented+1 to support open standards and even with more reason if it helps to move a step forward the API First initiative.
Comment #22
pounardMy 2 cents: I did a thorough comparison of various PHP OAuth2 libraries a few month ago in order to implement it for a client site, and the League's one was my choice.
I wouldn't change for anything, it has a very good support of the OAuth2 protocol, very secure, but there a few problems to go along:
OAuth2 is not a complicated protocol, but its implementation definitely is, and even if you use a good library, you MUST read and learn the full spec before going into it: a well designed and well written API is NOT ENOUGH to ensure security.
Comment #23
e0ipso@pounard there is a first draft of an implementation in https://www.drupal.org/project/simple_oauth (8.x-2.x). I'd appreciate if you could give it a quick review and log your concerns somewhere in the issue queue to get closer to a prototype for this issue.
Comment #24
pounard@e0ipso I can't promise you I will, but I'll try to save some to time to do this during the next week.
Comment #25
hampercm commented@e0ipso Yes, definitely a +1 for OAuth2 in core from me. Considering the league's OAuth2 library is already utilized in the simple_oauth module, it makes sense to me to stick with that, unless there is a great advantage to using another library. From other feedback, it appears there isn't a major difference, so I'd also +1 sticking with what is already there, the League's OAuth2 library.
Comment #26
e0ipsoI'm not familiar with this whole experimental module process. Should I wait until I get green light from all the framework and/or product managers before working on a patch?
It seems that Dries Buytaert (BDFL, Product Manager) gave his OK to this idea in his blog http://buytaert.net/improving-drupal-8-api-first-json-api-oauth2.
I am currently holding on to this (as stated in the Next Steps section in the IS), but I want to make sure that they are not waiting for an actual patch before doing an evaluation.
Comment #27
wim leersRegarding which grants to include: it seems everyone wants the password grant. So let's do only the password grant in the patch that brings OAuth 2 to Drupal 8.3. So that's the MVP then. More grants can be added in future commits.
(Because this would be an "alpha" experimental module, we would be able to add new functionality even after 8.3.0 is released.)
Comment #28
e0ipso@Wim Leers, as discussed in https://youtu.be/Hk0L1vfgAOI?t=6m30s I think this is a very good way to simplify the scope and have a simpler patch.
Copying from #11, I think that Password Grant is a good idea:
After that is committed, adding the Refresh Grant will be just a small plugin class (grants are plugins).
Comment #29
dawehnerWhen I understand it correctly this is the most common uscase of running Drupal headless. Not as 3rd party app, nor as dedicated web app accessing your data over the wire, but rather as 1st party client side application.
Given that supporting just the password one sounds totally sensible.
Comment #30
e0ipsoWould it be fair to say that we have achieved:
When consensus has been reached, we should move this to RTBC.
Comment #31
wim leersI agree, I think we've reached consensus. The password grant is the MVP. #27 + #28 + #29 agree. A week since #29 without additional pro/con messages suggests few people actually have strong enough opinions to leave a comment.
So, moving to RTBC.
Comment #32
hampercm commented+1 for Password Grant. I'd also like to see Refresh Grant, as it enables following the OAuth2 recommendation of short access token lifetimes.
Comment #33
wim leersPer #2858592: *DRAFT* Proposed product goals for Drupal 8.4/8.5(+) core. Updated #2757967 accordingly: #2757967-27: API-first initiative.
Comment #34
edischI'd like to get a patch against 8.8.x going with the password grant using @e0ipso's simple_oauth module as the foundation. Any work already been done on this?
Comment #35
edischCopied over from: https://www.drupal.org/project/drupal/issues/1148990#comment-13168118
We talked about this today in the Drupal slack. Specifically @gabesullice mentioned:
Authentication flows were also discussed, things like:
These are not possible at the moment without a password. Even when authenticated with a provider (JWT, Simple OAuth, etc), the current password must be sent in the request in order to make changes to the user entity.
There's some security related points to consider:
---
These are probably points for later down the line. I agree with password grant being the MVP.
Comment #36
edischNow that JSON:API is in core as of 8.7 we should start thinking about next steps on including a recommended authentication provider in core.
Comment #37
e0ipsoAs the maintainer of Simple OAuth I can say that there is no one pushing this forward, as far as I know.
The blocker at the moment is: Is this something we want from a product perspective?
Comment #38
quietone commentedThe Ideas project is being deprecated. As discussed in a core committer meeting issues that are adding modules are being moved to the Drupal CMS project for discussion.
Comment #39
tim.plunkettComment #40
pameeela commentedThis wouldn't go into vanilla Drupal CMS, but would make sense for site templates with this requirement.