公司内部工具统一使用passport认证登录,于是写这么一个小plugin,用来给dancer做的网站使用统一认证。 passport的原理很简单,将原先的页面url带入session转到passport的login,然后由passport通过user/password或者kerberos确认是否正确,并返回一个ticket参数,然后拿这个ticket再到passport的verify上校验一次username,正确的话写入session即可。代码如下:
package Dancer::Plugin::Auth::Passport;
use Dancer ':syntax';
use Dancer::Plugin;
use Furl;
use warnings;
use strict;
our $VERSION = '0.01';
my $settings = plugin_setting;
my $PASSPORT_HOST = $settings->{passport_host} || 'passport.company.com';
sub _auth_passport {
if ( !session('username') ) {
my $req_url = request->scheme .'://'. request->header('Host') . request->uri;
if ( defined(my $ticket = params->{'ticket'}) ) {
my $passport_url = "https://${PASSPORT_HOST}/verify.php?t=${ticket}";
my $furl = Furl->new( timeout => 10, headers => ['Referer' => "$req_url"] );
my $res = $furl->get($passport_url);
redirect "https://${PASSPORT_HOST}/login.php?forward=${req_url}" unless $res->is_success;
session username => $res->content;
redirect session->{'original_url'};
} else {
session original_url => ${req_url};
redirect "https://${PASSPORT_HOST}/login.php?forward=${req_url}";
};
};
};
register 'auth_passport' => \&_auth_passport;
register_plugin;
true;
__END__
使用方法如下:
package DancerApp;
use Dancer ':syntax';
use Dancer::Plugin::Auth::Passport;
hook 'before' => sub { auth_passport };
get '/' => sub { return 'Hello Passport' };
true;
完毕。