Token-based web service authentication to core
All: See http://drupal.org/node/46145 I'm going to make sure that Ben is signed up to the dev list. He's on the board of the PHP User's Group here in Vancouver and is a pretty kick ass programmer. For now, making sure this gets the views it deserves. This opens the door to the type of interactions that, e.g. Flickr, does remotely, and lots of rich inter-site functionality.
I'm building a new website in Drupal and there are some administrative web services that I would like to make available to middleware together a legacy system. I did some research into Drupal's XMLRPC system and figured that token based authentication in the core would be useful.
This is what I have sketched out on a napkin:
Scenario: Client wants to create some new data in the system. This is the process:
1. Client requests a service token, sends username/password of a Drupal user 2. Drupal loads the $user matching the crudentials - creates a random alphanumeric token to send back to the user - serializes, and caches the $user object, key = md5(token + ip address of client) - sends the token back to the client 3. Client makes an RPC call to say: module.createListing($token, $arg1,$arg2,...) 4. In createListing(...) -- Checks the token, if valid does it's thing, otherwise, returns an error message.
I think it would take a fairly small amount of code to accomplish the above. I haven't given a lot of thought about Drupal's external authentication system though. I'm not too familiar with it, but maybe somebody can fill me it. For this system I may write my own version of user_authenticate() without the variable_get ('user_register',1) in it so some malicous person doesn't create an unlimited number of random users in the system.
Any thoughts or previous work on this? I would like it to be implemented in core, but it would probably be just as easy to implement as a module. Since modules will depend on the functionality, I want to avoid the logic of checking if the module is enabled or not.
I took a look at how the blogapi module accomplishes authentication. It has $username,$password for each request, and does a user_load(...), which is alright, but I would like have a shared authentication for web services rather than rolling a custom one for every module that needs it.
Privileges and access can be combined into a xmlrpc_check_token ($token,$privilege) function, e.g:
xmlrpc_check_token($token,'access content')
It wouldn't take me long to write the code for this. I wanted some feedback from the community first before I dive into design/coding.
Boris Mann Vancouver 778-896-2747 San Francisco 415-367-3595 SKYPE borismann http://www.bryght.com
The proposed token authentication sounds like it would also be useful in allowing non-public feeds to be pulled from Drupal sites in order for them to be aggregated. Dan On 24/01/06, Boris Mann <boris@bryght.com> wrote:
All:
See http://drupal.org/node/46145
I'm going to make sure that Ben is signed up to the dev list. He's on the board of the PHP User's Group here in Vancouver and is a pretty kick ass programmer. For now, making sure this gets the views it deserves.
This opens the door to the type of interactions that, e.g. Flickr, does remotely, and lots of rich inter-site functionality.
I'm building a new website in Drupal and there are some administrative web services that I would like to make available to middleware together a legacy system. I did some research into Drupal's XMLRPC system and figured that token based authentication in the core would be useful.
This is what I have sketched out on a napkin:
Scenario: Client wants to create some new data in the system. This is the process:
1. Client requests a service token, sends username/password of a Drupal user 2. Drupal loads the $user matching the crudentials - creates a random alphanumeric token to send back to the user - serializes, and caches the $user object, key = md5(token + ip address of client) - sends the token back to the client 3. Client makes an RPC call to say: module.createListing($token, $arg1,$arg2,...) 4. In createListing(...) -- Checks the token, if valid does it's thing, otherwise, returns an error message.
I think it would take a fairly small amount of code to accomplish the above. I haven't given a lot of thought about Drupal's external authentication system though. I'm not too familiar with it, but maybe somebody can fill me it. For this system I may write my own version of user_authenticate() without the variable_get ('user_register',1) in it so some malicous person doesn't create an unlimited number of random users in the system.
Any thoughts or previous work on this? I would like it to be implemented in core, but it would probably be just as easy to implement as a module. Since modules will depend on the functionality, I want to avoid the logic of checking if the module is enabled or not.
I took a look at how the blogapi module accomplishes authentication. It has $username,$password for each request, and does a user_load(...), which is alright, but I would like have a shared authentication for web services rather than rolling a custom one for every module that needs it.
Privileges and access can be combined into a xmlrpc_check_token ($token,$privilege) function, e.g:
xmlrpc_check_token($token,'access content')
It wouldn't take me long to write the code for this. I wanted some feedback from the community first before I dive into design/coding.
Boris Mann Vancouver 778-896-2747 San Francisco 415-367-3595 SKYPE borismann http://www.bryght.com
-- Dan Karran dan@karran.net www.dankarran.com
On Tuesday 24 January 2006 12:04, Boris Mann wrote:
1. Client requests a service token, sends username/password of a Drupal user 2. Drupal loads the $user matching the crudentials - creates a random alphanumeric token to send back to the user - serializes, and caches the $user object, key = md5(token + ip address of client) - sends the token back to the client 3. Client makes an RPC call to say: module.createListing($token, $arg1,$arg2,...) 4. In createListing(...) -- Checks the token, if valid does it's thing, otherwise, returns an error message.
Two questions: 1. Expiration of the token -- has that been considered? Probably these should have a very limited lifetime. Reasons: a. The token may be stored in a temp file on the remote system; we might all agree that's a bad idea, but we can't stop them from doing so. If the remote is later compromised, then so are we. b. If we accumulate too many such tokens that are out there in the world and valid, a large Drupal site that has too many of them may become vulnerable to a brute-force attack. 2. This sounds a lot like a miniature Kerberos. Has anyone done anything to Kerberize Drupal itself? One comment: This is probably something that, if it ends up in core, should be disabled by default and turned on by the sysadmins who want/need it. Err on the side of paranoia when it comes to authentication. #2 may be a dumb question; it isn't something I've had time to research. If so, please feel free to thwack me with an RTFM. :-) None of the above are meant to criticize the concept; I think it might be useful in certain situations, and adding it wouldn't take away anything that exists now, especially if it's an add-on rather than core. Scott -- ------------------------------------------------------------------------------- Scott Courtney Drupal user name: "syscrusher" http://drupal.org/user/9184 scott at 4th dot com Drupal projects: http://drupal.org/project/user/9184 Sandbox: http://cvs.drupal.org/viewcvs/drupal/contributions/sandbox/syscrusher
On 1/24/06, Syscrusher <scott@4th.com> wrote:
On Tuesday 24 January 2006 12:04, Boris Mann wrote:
1. Client requests a service token, sends username/password of a Drupal user 2. Drupal loads the $user matching the crudentials - creates a random alphanumeric token to send back to the user - serializes, and caches the $user object, key = md5(token + ip address of client)
Please do not use the IP address. Users behind proxy pools will be excluded. Thing of all the poor souls that use AOL as an ISP, some corporate networks, and even some countries. Think of something else. The PHPSESSID perhaps?
On 24-Jan-06, at 11:21 AM, Syscrusher wrote:
2. This sounds a lot like a miniature Kerberos. Has anyone done anything to Kerberize Drupal itself?
One comment: This is probably something that, if it ends up in core, should be disabled by default and turned on by the sysadmins who want/need it. Err on the side of paranoia when it comes to authentication.
The drupal.modules DrupalAuth is insecure by default. This might prove the basis for a replacement of that. I've indicated my desire for Drupal to choose a federated login standard and have this in core by default, with other solutions still being pluggable, as we have today.
#2 may be a dumb question; it isn't something I've had time to research. If so, please feel free to thwack me with an RTFM. :-)
I think you could build a Kerberos module. -- Boris Mann Vancouver 778-896-2747 San Francisco 415-367-3595 SKYPE borismann http://www.bryght.com
I think you could build a Kerberos module.
The current popular option for most kerb + php set ups I've seen (like one in my univ, which runs horde/imp) is to use standard auth systems to authenticate, and pass on HTTP headers with authentication tokens to the PHP script. Seems to work ok. -Arnab
On 1/24/06, Arnab Nandi <arnabdotorg@gmail.com> wrote:
I think you could build a Kerberos module.
The current popular option for most kerb + php set ups I've seen (like one in my univ, which runs horde/imp) is to use standard auth systems to authenticate, and pass on HTTP headers with authentication tokens to the PHP script. Seems to work ok.
-Arnab
From what I've seen Kerberos isn't a simple thing to implement. See: http://web.mit.edu/kerberos/www/dialogue.html which is a good high level overview of the system (and it's still a little confusing).
After reading the Kerberos link above again, it raised an interesting issue about mutual authentication. In terms of the web service, how can the client be sure that it's sending it's crudentials to the right server. Rather than overkilling the solution, in my mod to the xml-rpc system I made it tie into Drupal's authentication using user_authenticate(). So web service authentication isn't much different from logging into the website through user/login. The session key is returned and instead of being passed as a cookie, is passed in the URL. In terms of security this isn't much less secure than regular PHP sessions. The exception is the web server log files. You will probably wind up with a lot of /xmlrpc.php?token={secret}. Not too big of a deal, unless your server gets compromised and somebody steals the keys that are still valid. Mind you, if they have access to your httpd logs, your probably have bigger problems than a few compromised session keys. Also the above would work seamlessly with HTTPS, which would be an easy way protect the data from sniffing. -- blog: http://www.mostlygeek.com
participants (6)
-
Arnab Nandi -
Benson Wong -
Boris Mann -
Dan Karran -
Khalid B -
Syscrusher