1 / 27

Web Services with OAuth

Web Services with OAuth. What is OAuth?. A simple open standard for API Authentication. Do we need it? We’ve got OpenID. Not a replacement, a complementary API. OAuth is Authorization, Openid is Authentication

dolf
Download Presentation

Web Services with OAuth

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Web Services with OAuth

  2. What is OAuth? • A simple open standard for API Authentication

  3. Do we need it? We’ve got OpenID • Not a replacement, a complementary API. • OAuth is Authorization, Openid is Authentication • OpenID users don’t have passwords, so can’t ask them for that when they try to access the API • OAuth is token based, does not require password

  4. A bit more about OAuth • Not a new idea - FlickrAuth, Google AuthSub, BBAuth, etc. • Open Standard - http://oauth.net/ • Wide industry support • AOL, Eye-Fi, Facebook, Garmin, Google, LinkedIn, Ma.gnolia, Microsoft, MySpace, Plaxo, Pownce, Salesforce, Songbird, Veodia, and Yahoo!. and more! • Easy to understand • Easy to implement

  5. The Usual Suspects

  6. The Conversation • <me> Hey Appfresh update my iusethis count<appfresh> Lemme check with iusethis • <appfresh> Hey iusethis, can I update marcus’ apps?<iusethis> Here’s a ticket, give that to him,and I’ll check with him* iusethis hands appfresh a request token • <appfresh> Hey marcus, get this ticket stamped with iusethis so I can update your data for you, please<me> *meh*, allright • * appfresh opens a browser window to iusethis<iusethis> Marcus, you fine with appfresh updating your counts?<me> Go ahead already, I’m waiting here<iusethis> Ok, here’s a stamp for your ticket.* iusethis marks the token as approved • * appfresh hands the request token over to iusethis and gets an access token in return once iusethis sees that it is approved* appfresh updates my iusethis counts. *yay*

  7. The data flow • Consumer must be registered with service • Consumer sends a signed OAuth request to the request_token endpoint, service provider returns a token as a post body in the response content • Consumer opens the user auth endpoint with the specified token. if web service, provide a callback to redirect back after auth. user verifies token, and returns to service • Consumer hits access token endpoint with request token and gets a valid access token

  8. The OAuth request • POST/GET Request • oauth_consumer_key => 'foo', • oauth_consumer_secret => 'bar', • oauth_request_method => 'POST', • signature_method => 'HMAC-SHA1', • oauth_timestamp => '1191242090', • oauth_nonce => 'hsu94j3884jdopsl',

  9. Adding this for your Catalyst based API • We need to store data somewhere • I’ll use a DBIC model in this example: • DB::Consumer • DB::RequestToken • DB::AccessToken • Then we just use Net::OAuth directly in the controller:

  10. request_token method • my $oauth_params = $c->get_oauth_parameters(@params); • my $consumer=$c->model('DB::Consumer')->find( • $c->req->params->{consumer_secret}) • or $c->detach('/usererror', • ["Consumer not registered"]); • my $request = eval { • Net::OAuth::RequestTokenRequest->new( • request_url => $c->req->uri, • request_method => $c->req->method, • consumer_secret => $consumer->secret, • signature_key => $c->get_signature_key, • ) • }; # handle errors here • $c->stash->{requesttoken}= • $consumer->new_requesttoken($request);

  11. verifying the request • sub verify_access : Local { • my ($self,$c)=@_; • $c->res->redirect($c->uri_for(‘/login’) • unless $c->user_exists; • my @params = qw/consumer_key signature_method • signature timestamp nonce token version/; • # find and validate token • return $c->res->redirect('/login') • unless $c->user_exists; • if($c->req->params->{verify}) { • $token->verified(1);$token update; • } • }

  12. access_token • my ($self,$c)=@_; • my $consumer= ... # like previous • my $request = eval { Net::OAuth::AccessTokenRequest • ->new( • request_url => $c->uri_for( • '/oauth/access_token'), • request_method => $c->req->method, • consumer_secret => $consumer->secret, • token_secret => $request_token->secret, • signature_key => $signature_key, }; • $token= $consumer • ->get_access_token($oauth_params{token}) || • $c->detach('/usererror',['Request token not found']); • $c->stash->{access_token}=$token • ->create_access_token($token);

  13. A bit of work • In addition you need a method to verify that the access token was provided for api methods • A bit of a hassle right now • Will commit a server example to catalyst-trunk shortly • Watch for Catalyst-Controller-OAuth sometime in the near future. • Might also be a Reaction component

  14. Jifty • Jifty::Plugin::OAuth makes this easy. • Add this to your config file : • And presto: framework: Plugins: - OAuth: {}

  15. Jifty Screenshot

  16. Jifty Screenshot

  17. Jifty continued • Make sure that /oauth/authorize requires login. • Make sure that /oauth/request_token and /oauth/access_token doesn’t. • In beta. Still has some limitations. Consumers has to be manually registered.

  18. Example: GMail contacts at OAuth

  19. Example: GMail contacts at OAuth

  20. Behind the curtain • my $request = Net::OAuth ->request("request token")->new( $c->_default_request_params, request_url => $c->config->{request_token_endpoint}, extra_params => { scope=> $c->config->{request_scope}, }); • $request->sign($c->_get_key); • my $res = $ua->request(GET $request->to_url);

  21. Behind the curtain • $request = Net::OAuth->request('user auth')->new( token => $response->token, callback => $c->uri_for('/callback'),); • return $c->res->redirect($request->to_url($c->config->{user_auth_endpoint}));

  22. Example: GMail contacts at OAuth

  23. Behind the curtain • my $response = Net::OAuth->response('user auth') ->from_hash($c->req->params); • my $request = Net::OAuth->request("access token") ->new( $c->_default_request_params,request_url => $c->config->{access_token_endpoint},token => $response->token,token_secret => ''); • $request->sign($c->_get_key); • my $res = $ua->request(GET $request->to_url);

  24. Behind the curtain • $response = Net::OAuth ->response('access token') ->from_post_body($res->content); • $c->session->{token}= $response->token; • # use the tokenmy $request = Net::OAuth->request("protected resource")->new($c->_default_request_params,request_url => $c->config->{contacts_feed_url},token => $c->session->{token},token_secret => '',); • # sign, lwpmy $res = $ua->request(GET($request->request_url, Authorization => $request->to_authorization_header));

  25. Get the Source • Ported from the Original CGI::App example included in Net::OAuth • Get the source in Catalyst repo • http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/OAuthExample

  26. Questions?

  27. Thank you! marcus@nordaaker.com

More Related