Nordaaker Web Services with OAuth. What is OAuth? A simple open standard for API Authentication.

  • Published on
    16-Dec-2015

  • View
    213

  • Download
    1

Embed Size (px)

Transcript

<ul><li> Slide 1 </li> <li> Nordaaker Web Services with OAuth </li> <li> Slide 2 </li> <li> What is OAuth? A simple open standard for API Authentication </li> <li> Slide 3 </li> <li> Do we need it? Weve got OpenID Not a replacement, a complementary API. OAuth is Authorization, Openid is Authentication OpenID users dont have passwords, so cant ask them for that when they try to access the API OAuth is token based, does not require password </li> <li> Slide 4 </li> <li> A bit more about OAuth Not a new idea - FlickrAuth, Google AuthSub, BBAuth, etc. Open Standard - http://oauth.net/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 </li> <li> Slide 5 </li> <li> The Usual Suspects </li> <li> Slide 6 </li> <li> The Conversation Hey Appfresh update my iusethis count Lemme check with iusethis Hey iusethis, can I update marcus apps? Heres a ticket, give that to him,and Ill check with him * iusethis hands appfresh a request token Hey marcus, get this ticket stamped with iusethis so I can update your data for you, please *meh*, allright * appfresh opens a browser window to iusethis Marcus, you fine with appfresh updating your counts? Go ahead already, Im waiting here Ok, heres 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* </li> <li> Slide 7 </li> <li> 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 </li> <li> Slide 8 </li> <li> The OAuth request POST/GET Request oauth_consumer_key =&gt; 'foo', oauth_consumer_secret =&gt; 'bar', oauth_request_method =&gt; 'POST', signature_method =&gt; 'HMAC-SHA1', oauth_timestamp =&gt; '1191242090', oauth_nonce =&gt; 'hsu94j3884jdopsl', </li> <li> Slide 9 </li> <li> Adding this for your Catalyst based API We need to store data somewhere Ill use a DBIC model in this example: DB::Consumer DB::RequestToken DB::AccessToken Then we just use Net::OAuth directly in the controller: </li> <li> Slide 10 new( request_url =&gt; $c-&gt;req-&gt;uri, request_method =&gt; $c-&gt;req-&gt;method, consumer_secret =&gt; $consumer-&gt;secret, signature_key =&gt; $c-&gt;get_signature_key, ) }; # handle errors here $c-&gt;stash-&gt;{requesttoken}= $consumer-&gt;new_requesttoken($request);"&gt; </li><li> request_token method my $oauth_params = $c-&gt;get_oauth_parameters(@params); my $consumer=$c-&gt;model('DB::Consumer')-&gt;find( $c-&gt;req-&gt;params-&gt;{consumer_secret}) or $c-&gt;detach('/usererror', ["&gt;new( request_url =&gt; $c-&gt;req-&gt;uri, request_method =&gt; $c-&gt;req-&gt;method, consumer_secret =&gt; $consumer-&gt;secret, signature_key =&gt; $c-&gt;get_signature_key, ) }; # handle errors here $c-&gt;stash-&gt;{requesttoken}= $consumer-&gt;new_requesttoken($request); </li> <li> Slide 11 </li> <li> verifying the request sub verify_access : Local { my ($self,$c)=@_; $c-&gt;res-&gt;redirect($c-&gt;uri_for(/login) unless $c-&gt;user_exists; my @params = qw/consumer_key signature_method signature timestamp nonce token version/; # find and validate token return $c-&gt;res-&gt;redirect('/login') unless $c-&gt;user_exists; if($c-&gt;req-&gt;params-&gt;{verify}) { $token-&gt;verified(1);$token update; } </li> <li> Slide 12 </li> <li> access_token my ($self,$c)=@_; my $consumer=... # like previous my $request = eval { Net::OAuth::AccessTokenRequest -&gt;new( request_url =&gt; $c-&gt;uri_for( '/oauth/access_token'), request_method =&gt; $c-&gt;req-&gt;method, consumer_secret =&gt; $consumer-&gt;secret, token_secret =&gt; $request_token-&gt;secret, signature_key =&gt; $signature_key, }; $token= $consumer -&gt;get_access_token($oauth_params{token}) || $c-&gt;detach('/usererror',['Request token not found']); $c-&gt;stash-&gt;{access_token}=$token -&gt;create_access_token($token); </li> <li> Slide 13 </li> <li> 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 </li> <li> Slide 14 </li> <li> Jifty Jifty::Plugin::OAuth makes this easy. Add this to your config file : And presto: framework: Plugins: - OAuth: {} </li> <li> Slide 15 </li> <li> Jifty Screenshot </li> <li> Slide 16 </li> <li> Slide 17 </li> <li> Jifty continued Make sure that /oauth/authorize requires login. Make sure that /oauth/request_token and /oauth/access_token doesnt. In beta. Still has some limitations. Consumers has to be manually registered. </li> <li> Slide 18 </li> <li> Example: GMail contacts at OAuth </li> <li> Slide 19 </li> <li> Slide 20 new( $c-&gt;_default_request_params, request_url =&gt; $c-&gt;config-&gt;{request_token_"&gt; new( $c-&gt;_default_request_params, request_url =&gt; $c-&gt;config-&gt;{request_token_" title="Behind the curtain my $request = Net::OAuth -&gt;request("request token")-&gt;new( $c-&gt;_default_request_params, request_url =&gt; $c-&gt;config-&gt;{request_token_"&gt; </li><li> Behind the curtain my $request = Net::OAuth -&gt;request("request token")-&gt;new( $c-&gt;_default_request_params, request_url =&gt; $c-&gt;config-&gt;{request_token_endpoint}, extra_params =&gt; { scope=&gt; $c-&gt;config-&gt;{request_scope}, }); $request-&gt;sign($c-&gt;_get_key); my $res = $ua-&gt;request(GET $request-&gt;to_url); </li> <li> Slide 21 </li> <li> Behind the curtain $request = Net::OAuth-&gt;request('user auth')-&gt;new( token =&gt; $response-&gt;token, callback =&gt; $c-&gt;uri_for('/callback'), ); return $c-&gt;res-&gt;redirect( $request-&gt;to_url($c-&gt;config-&gt;{user_auth_endpoint})); </li> <li> Slide 22 </li> <li> Example: GMail contacts at OAuth </li> <li> Slide 23 new( $c-&gt;_default_request_params, request_url =&gt; $c-&gt;config-&gt;{access_token_endpoint}, token =&gt; $response-&gt;token, token_secret =&gt; ''); $request-&gt;sign($c-&gt;_get_key); my $res = $ua-&gt;request(GET $request-&gt;to_url);"&gt; response('user auth') -&gt;from_hash($c-&gt;req-&gt;params); my $request = Net::OAuth-&gt;request("access token""&gt; </li><li> Behind the curtain my $response = Net::OAuth-&gt;response('user auth') -&gt;from_hash($c-&gt;req-&gt;params); my $request = Net::OAuth-&gt;request("access token") -&gt;new( $c-&gt;_default_request_params, request_url =&gt; $c-&gt;config-&gt;{access_token_endpoint}, token =&gt; $response-&gt;token, token_secret =&gt; ''); $request-&gt;sign($c-&gt;_get_key); my $res = $ua-&gt;request(GET $request-&gt;to_url); </li> <li> Slide 24 new($c- &gt;_default_request_params, request_url =&gt; $c-&gt;config-&gt;{contacts_feed_url}, token =&gt; $c-&gt;session-&gt;{token}, token_secret =&gt; '',); # sign, lwp my $res = $ua-&gt;request(GET($request-&gt;request_url, Authorization =&gt; $request-&gt;to_authorization_header));"&gt; </li><li> Behind the curtain $response = Net::OAuth -&gt;response('access token') -&gt;from_post_body($res-&gt;content); $c-&gt;session-&gt;{token}= $response-&gt;token; # use the token my $request = Net::OAuth-&gt;request("protected resource")-&gt;new($c- &gt;_default_request_params, request_url =&gt; $c-&gt;config-&gt;{contacts_feed_url}, token =&gt; $c-&gt;session-&gt;{token}, token_secret =&gt; '',); # sign, lwp my $res = $ua-&gt;request(GET($request-&gt;request_url, Authorization =&gt; $request-&gt;to_authorization_header)); </li> <li> Slide 25 </li> <li> 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/e xamples/OAuthExample </li> <li> Slide 26 </li> <li> Nordaaker Questions? </li> <li> Slide 27 </li> <li> Nordaaker Thank you! marcus@nordaaker.com </li> </ul>

Recommended

View more >