I believe it would make sense for services_oauth to provide two separate authentication methods: the current three-legged oAuth method, plus a separate two-legged method for API key authentication only. Three-legged oAuth includes an extra step of sending the end user to the site to authorize the app that's using the API key, and in a lot of situations that's unnecessary, because the user holding the API key has all the permissions they need already. I have two-legged oAuth working in 6.x-3.x as a separate module, but I think it should probably be part of services_oauth. I'll work on a 7.x-3.x patch first.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

kylebrowning’s picture

Would love to see this.

ksenzee’s picture

Status: Active » Needs review
FileSize
2.03 KB

It turns out to be really simple. All you have to do is default to requiring only 'consumer' credentials (instead of 'token'), and - most importantly - loading the user that owns the API key. Patch attached.

kylebrowning’s picture

Status: Needs review » Reviewed & tested by the community

This looks great.

teunis’s picture

FileSize
1.32 KB

This approach re-uses existing mechanisms and checks for authentication type 'consumer' instead of 'token'.
Tested with Drupal 7
Unfortunately, while there's a form to edit this already present, I've no idea how it's supposed to be called.

apologies for the conflicting patch with above, but I've spent the last week building this by slowly testing REST and XMLRPC across some - it turns out buggy - tools. If anyone is interested in a python test or a jsAuth-based test (Titanium/Appcentre mobile dev) I'd love to post them.

kylebrowning’s picture

kylebrowning’s picture

Status: Reviewed & tested by the community » Needs work
ksenzee’s picture

I second Kyle's question in #5. Without the patch he mentions, the patch in #4 still doesn't let you use two-factor oAuth, because you can't get to the form where you set each resource as requiring consumer-only auth.

I don't think the two patches in this issue are incompatible. The patch in #2 lets you set an entire service up as two-factor oAuth, and the patch in #4 lets you set up just certain resources to use two-factor oAuth. They're both useful approaches. I don't think #4 is a substitute for #2, however. People who want a substitute for the old keyauth method shouldn't have to click themselves to death setting up every resource in their service as two-factor oAuth. They should just be able to choose two-factor oAuth as an authentication method and be done with it.

teunis’s picture

I couldn't use patch #5 - I manually updated the record to test it. So either combine #4 with the readd patch - or consider them separate parts, I'd think.
I myself wouldn't use the first patch - while the form looks like it's nice, it adds a second path of logic that isn't as obvious unless you've spent a few days reading OAuth documents.

As I understand it:
- Three legged (token) OAuth - B gives A a key, A signs into B, gets asked to confirm, B sends A a token via callback (or oob - but I don't know how this will work in drupal) and A uses token to communicate.
- Two legged (consumer key) OAuth - B gives A a key, A signs into B using key and allowed access as per that key on that account.

I'm using the second because I'm working with phone apps, where the token method isn't reasonable without some way of passing the token back out-of-band.

teunis’s picture

Oh, my test client is at this point

ksenzee’s picture

Your understanding of two-legged vs. three-legged oAuth is correct. But I don't understand your point about the second path of logic. If you're using two-legged oAuth, you want consumer-based authentication, and you should load the consumer's account. The logic is no more complicated than that.

teunis’s picture

The first patch 'modifies' the path based on a second rule. Basically : if the value is set, bypass endpoint configuration and force two-legged. While it's probably easier to set up, it makes the logic a bit more complicated. It's not likely to break anything - unless one was using something other than token authentication on the endpoint (currently not possible without manually updating database).
Also, should there be any further auth mechanisms set up, it makes it a bit harder to spot where to add them. From what I can tell, the original forms for endpoint auth were (note, there's nothing that says how they work): unsigned_consumer, consumer, token
where it defaulted to token if none were present. The specs don't suggest any more will be added, so perhaps simplifying to 'two legged' or 'three legged' might be the way to go.

Really, the first patch is the faster to get "to operational". Use it where one wants a special case where "two legged OAuth" is intended as only or primary.
I hope my feedback helps explain why I took the route I did.

kylebrowning’s picture

It sounds to me like one way is, an end all be all for the specific endpoint, and the second is for individual resources/methods.

I don't feel like we should combine the patches between this node and #1154420 b/c one is certainly a functionality request for services and the other is certain and oAuth fix for services. While they are btw needed for this to work its not needed.
What I need from you guys is to tell me the exact things you need in order for this two work.

Im fine with combining the two patches here as I understand both use cases. More granular settings need to override the overall setting etc.

And lastly we need to make sure it all works so Im all down for helping and Im gonna start by finishing #1154420: Readd support for rich options for resources - needed by auth mechanism.

Unfortunatly I don't think this will make it into 3.1 as were going to release that very soon.

ksenzee’s picture

It seems to me #1154420: Readd support for rich options for resources - needed by auth mechanism is higher priority than either patch here so starting there is great.

The patch in #4 cleans up the way in which the global $user is overridden. In cases where the auth is consumer level, it loads the consumer's account as the global $user. So it's a sensible patch regardless of #2, and in fact probably belongs in a separate issue. It's dependent on #1154420: Readd support for rich options for resources - needed by auth mechanism though - it can't even be tested until that patch is in.

More granular settings need to override the overall setting etc.

The patch in #2 doesn't take that approach. If you've chosen two-legged oAuth, you get two-legged oAuth, and you can't override that using the settings form (especially since the form doesn't even exist at the moment). When #1154420: Readd support for rich options for resources - needed by auth mechanism lands, we can change the patch in #2 to take one of two approaches:

1. make the 'token' option unavailable in the settings form if you've chosen the two-legged method
2. make the settings form unavailable entirely if you've chosen the two-legged method

Either option makes sense to me. I see two-legged oAuth as a simple replacement for old-style key auth, and would like to keep it as simple as possible, so I lean towards 2, but 1 is fine as well.

kylebrowning’s picture

I like #2 in the list of items on comment #13 :P

teunis’s picture

I've come up with a better approach for what I was working with - this doesn't conflict with the readd work, although I'm not entirely sure what the readd work is supposed to do. On mine, it does nothing.

So this patch combines my previous one with a menu to configure it.
It appears on services under "authentication"

under 'context' is added 'authorization' and 'required authentication' - allowing for two-legged, three-legged and potentially 'none', as well as other mechanisms if anyone dreams up any. (ignoring unsigned_consumer for now)

teunis’s picture

Status: Needs work » Needs review

tested with services-3.1

kylebrowning’s picture

Version: 7.x-3.x-dev » 6.x-3.x-dev
Status: Needs review » Patch (to be ported)

I think this looks great.and it seems to work from my quick overview.

Im happy with committing #15 once its been ported to D6.

teunis’s picture

FileSize
4.28 KB

Here's an attempt at a D6 version of the patch. I haven't got any services installations under D6, so it's relatively untested.

teunis’s picture

Status: Patch (to be ported) » Needs review
kylebrowning’s picture

Status: Needs review » Reviewed & tested by the community

Looks good.

RTBC

jobeirne’s picture

Rerolling patch from #15 to play nicely with Drush make.

jobeirne’s picture

Oops. Wrong patch; _this one_ should work with Drush.

marcingy’s picture

Title: Two-legged oAuth authentication method » Support drush with Two-legged oAuth authentication method
Version: 6.x-3.x-dev » 7.x-3.x-dev
Status: Reviewed & tested by the community » Needs work

@jobeirne we have policy of fixing in d7 and then backporting - I have tidied up the patch in #18 and committed that. If you could re-roll a patch that makes the changes required for drush make we will certainly look to get them committed, this way we end up with a patch that is kept in sync across the 2 versions.

Patch in #18 has been committed.

ksenzee’s picture

Title: Support drush with Two-legged oAuth authentication method » Two-legged oAuth authentication method

We don't have to do anything particular to support Drush make. It's just that if someone posts a patch in an issue that doesn't apply cleanly with Drush make, you can't use it in your Drush makefile. So often people will post a reroll that does apply cleanly.

marcingy’s picture

Status: Needs work » Fixed

The issue was that patches for d6 and d7 didn't apply cleanly with git apply then I assume. (I not a drush make user). Marking the issue as fixed if there are problems shout!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.