Dancer2-Plugin-OIDC
view release on metacpan or search on metacpan
# Dancer2::Plugin::OIDC
This plugin makes it easy to integrate the OpenID Connect protocol into a Dancer2 application.
It essentially uses the [OIDC-Client](https://metacpan.org/dist/OIDC-Client) distribution.
## Features
- creates the endpoint used by the provider to redirect the user back to your application
- retrieves the provider metadata and JWK keys when the application is launched
- redirects the browser to the authorize URL to initiate an authorization code flow
- gets the token(s) from the provider
- the tokens are stored for later use or for future requests
- refreshes access token if needed
- verifies a JWT token with support for automatic JWK key rotation
- introspects the access token
- gets the user information from the *userinfo* endpoint
- exchanges the access token
- redirects the browser to the logout URL
## Documentation
- [Plugin documentation](https://metacpan.org/pod/Dancer2::Plugin::OIDC)
- [Configuration](https://metacpan.org/pod/OIDC::Client::Config)
## Security Recommendation
t/auth-code-flow-IT.t view on Meta::CPAN
subtest 'Get public index page' => sub {
my $res = $test->request( GET '/');
ok($res->is_success, 'Status in success');
like( $res->content, qr/Welcome/, 'Expected text');
};
subtest 'Get protected page in error because invalid token format' => sub {
my $res = $test->request( GET '/protected' );
ok( $res->is_redirect, 'Response is a redirect' );
like( $res->header('Location'), qr[/authorize\?.+], 'redirection to the authorize endpoint' );
$res = follow_redirects($res);
is( $res->code, 401, 'Error in response' );
is( $res->content, 'Authentication Error', 'Correct response content' );
};
my $mock_crypt_jwt = Test::MockModule->new('Crypt::JWT');
$mock_crypt_jwt->redefine('decode_jwt' => sub {
my %params = @_;
my %claims = (
iss => 'my_issuer',
t/auth-code-flow-IT.t view on Meta::CPAN
);
return (
$params{decode_header} ? { 'alg' => 'whatever' } : (),
\%claims,
);
});
subtest 'Get protected page ok' => sub {
my $res = $test->request( GET '/protected?a=b&c=d' );
ok( $res->is_redirect, 'Response is a redirect' );
like( $res->header('Location'), qr[/authorize\?.+], 'redirection to the authorize endpoint' );
$res = follow_redirects($res);
ok( $res->is_success, 'Successful request' );
is( $res->content, 'my_subject is authenticated', 'Correct response content' );
like($res->request->uri, qr[/protected\?(a=b&c=d)|(c=d&a=b)$],
'Initial url is kept');
};
done_testing;
sub follow_redirects {
t/auth-code-flow-IT/MyProviderApp.pl view on Meta::CPAN
#!/usr/bin/env perl
use utf8;
use strict;
use warnings;
use Mojolicious::Lite;
# provider server routes
get('/wellknown' => sub {
my $c = shift;
my %url = (
authorization_endpoint => '/authorize',
end_session_endpoint => '/logout',
token_endpoint => '/token',
userinfo_endpoint => '/userinfo',
jwks_uri => '/jwks',
);
$c->render(json => {map { $_ => $url{$_} } keys %url});
});
get('/jwks' => sub {
my $c = shift;
$c->render(json => {});
});
# get '/authorize' in MyTestApp.pm (ugly but necessary)
post('/token' => sub {
( run in 1.990 second using v1.01-cache-2.11-cpan-55a6197bec7 )