diff --git a/Changes b/Changes index ed5da68..0444c13 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,11 @@ Revision history for Mojolicious-Plugin-OAuth2-Server +0.11 2015-03-19 + - update examples/oauth2_client.pl to work with latest version of + Mojolicious::Plugin::OAuth2. point to examples/ in the perldoc + - tweaks to perldoc to highlight that this is an implementation of + the "Authorization Code Grant" flow + 0.10 2015-03-17 - change token_type to be Bearer rather than bearer as this maps better for use in the Authorization header diff --git a/README.md b/README.md index 7ea3e2d..0383e01 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Authorization Server / Resource Server with Mojolicious # VERSION -0.10 +0.11 # SYNOPSIS @@ -77,6 +77,11 @@ Then in your controller: # DESCRIPTION +This plugin implements the OAuth2 "Authorization Code Grant" flow as described +at [http://tools.ietf.org/html/rfc6749#section-4.1](http://tools.ietf.org/html/rfc6749#section-4.1). It is not a complete +implementation of RFC6749, as it is rather large in scope. However the extra +functionality and flows may be added in the future. + This plugin enables you to easily (?) write an OAuth2 Authorization Server (AS) and OAuth2 Resource Server (RS) using Mojolicious. It implements the required flows and checks leaving you to add functions that are necessary, for example, @@ -590,6 +595,11 @@ oauth also becomes available to call in various controllers, templates, etc: $c->oauth( 'post_image' ) or return $c->render( status => 401 ); +# EXAMPLES + +There are more examples included with this distribution in the examples/ dir. +See examples/README for more information about these examples. + # CLIENT SECRET AND TOKEN SECURITY The auth codes and access tokens generated by the plugin should be unique. They diff --git a/examples/OAuth2Functions.pm b/examples/OAuth2Functions.pm index ebb3f6c..f94e84e 100644 --- a/examples/OAuth2Functions.pm +++ b/examples/OAuth2Functions.pm @@ -149,31 +149,34 @@ sub _verify_auth_code { ) { $c->app->log->debug( "Auth code does not exist" ) if ! $ac; - $c->app->log->debug( "Client secret does not match" ) - if ( $uri && $ac->redirect_uri ne $uri ); - $c->app->log->debug( "Auth code expired" ) - if ( $ac->expires->epoch <= time ); $c->app->log->debug( "Client secret does not match" ) if ! _check_password( $client_secret,$client->secret ); - if ( $ac->verified ) { - # the auth code has been used before - we must revoke the auth code - # and any associated access tokens (same client_id and user_id) - $c->app->log->debug( - "Auth code already used to get access token, " - . "revoking all associated access tokens" - ); - $ac->delete; - - if ( my $rs = $c->model->rs( 'Oauth2AccessToken' )->search({ - client_id => $client_id, - user_id => $ac->user_id, - }) ) { - while ( my $row = $rs->next ) { - $row->delete; + if ( $ac ) { + $c->app->log->debug( "Client secret does not match" ) + if ( $uri && $ac->redirect_uri ne $uri ); + $c->app->log->debug( "Auth code expired" ) + if ( $ac->expires->epoch <= time ); + + if ( $ac->verified ) { + # the auth code has been used before - we must revoke the auth code + # and any associated access tokens (same client_id and user_id) + $c->app->log->debug( + "Auth code already used to get access token, " + . "revoking all associated access tokens" + ); + $ac->delete; + + if ( my $rs = $c->model->rs( 'Oauth2AccessToken' )->search({ + client_id => $client_id, + user_id => $ac->user_id, + }) ) { + while ( my $row = $rs->next ) { + $row->delete; + } } } - } + } return ( 0,'invalid_grant' ); } diff --git a/examples/README b/examples/README index 3b60ed9..d69fcb8 100644 --- a/examples/README +++ b/examples/README @@ -41,16 +41,22 @@ Server What we have available in this examples/ directory: --------------------------------------------------- -examples/oauth2_client.pl - A Client +examples/oauth2_client.pl - A Client - this will need at least v1.51 of + the Mojolicious::Plugin::OAuth2 module examples/oauth2_server_simple.pl - An Authorization Server and Resource Server (that only runs one proc and will not retain - tokens across restarts) in its simplest form + tokens across restarts) in its simplest form. + it will not prompt for login or permission + so is useful to "emulate" an oauth2 server examples/oauth2_server_realistic.pl - An Authorization Server and Resource Server - (that can handle multiple procs and restarts + that will prompt for login and permission so + is a more realistic emulation. configured with + the examples/oauth2_db.json file. also of note + this can handle multiple procs and restarts without losing know tokens - although will - not scale, you should use a database really) + not scale, you should use a database really. examples/oauth2_server_db.pl - As above but uses a db (you will need mongodb and the perl MongoDB module to be able to use diff --git a/examples/oauth2_client.pl b/examples/oauth2_client.pl index ef1124d..1cae0c2 100644 --- a/examples/oauth2_client.pl +++ b/examples/oauth2_client.pl @@ -8,6 +8,7 @@ my $host = $ENV{HOST} // '127.0.0.1'; plugin 'OAuth2', { + fix_get_token => 1, overly_attached_social_network => { authorize_url => "https://$host:3000/oauth/authorize?response_type=code", token_url => "https://$host:3000/oauth/access_token", @@ -32,11 +33,12 @@ $self->delay( sub { my $delay = shift; - $self->get_token( overly_attached_social_network => $delay->begin ) + $self->oauth2->get_token( overly_attached_social_network => $delay->begin ) }, sub { - my( $delay,$token,$tx ) = @_; - return $self->render( json => $tx->res->json ); + my( $delay,$error,$data ) = @_; + return $self->render( error => $error ) if ! $data->{access_token}; + return $self->render( json => $data ); }, ); } diff --git a/lib/Mojolicious/Plugin/OAuth2/Server.pm b/lib/Mojolicious/Plugin/OAuth2/Server.pm index 35af454..d0bc781 100644 --- a/lib/Mojolicious/Plugin/OAuth2/Server.pm +++ b/lib/Mojolicious/Plugin/OAuth2/Server.pm @@ -11,7 +11,7 @@ Authorization Server / Resource Server with Mojolicious =head1 VERSION -0.10 +0.11 =head1 SYNOPSIS @@ -77,6 +77,11 @@ Then in your controller: =head1 DESCRIPTION +This plugin implements the OAuth2 "Authorization Code Grant" flow as described +at L. It is not a complete +implementation of RFC6749, as it is rather large in scope. However the extra +functionality and flows may be added in the future. + This plugin enables you to easily (?) write an OAuth2 Authorization Server (AS) and OAuth2 Resource Server (RS) using Mojolicious. It implements the required flows and checks leaving you to add functions that are necessary, for example, @@ -197,7 +202,7 @@ use MIME::Base64 qw/ encode_base64 decode_base64 /; use Carp qw/ croak /; use Crypt::PRNG qw/ random_string /; -our $VERSION = '0.10'; +our $VERSION = '0.11'; my %CLIENTS; my %AUTH_CODES; @@ -1069,6 +1074,11 @@ oauth also becomes available to call in various controllers, templates, etc: $c->oauth( 'post_image' ) or return $c->render( status => 401 ); +=head1 EXAMPLES + +There are more examples included with this distribution in the examples/ dir. +See examples/README for more information about these examples. + =head1 CLIENT SECRET AND TOKEN SECURITY The auth codes and access tokens generated by the plugin should be unique. They