Catalyst-Plugin-OIDC

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

# Catalyst::Plugin::OIDC

This plugin makes it easy to integrate the OpenID Connect protocol into a Catalyst 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
- manages the session : the tokens are stored to be used for next requests
- refreshes access token if needed
- verifies a JWT token with support for automatic JWK key rotation
- 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/Catalyst::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 = request('/');
  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 = request('/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, 'Expected error code');
  is($res->content, 'Authentication Error', 'Expected error message');
};

$mock_oidc_client->redefine('decode_jwt' => sub {
  {
    'iss'   => 'my_issuer',
    'exp'   => time + 30,
    'aud'   => 'my_id',
    'sub'   => 'my_subject',
    'nonce' => 'fake_uuid',
  }
});

subtest 'Get protected page ok' => sub {
  my $res = request('/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, 'Status in success');
  like($res->content, qr/my_subject is authenticated/, 'Expected text');
  like($res->request->uri, qr[/protected\?a=b&c=d$],
       'Initial url is kept');
};

done_testing;

sub follow_redirects {

t/lib/MyProviderApp/app.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 '/authorize' in MyCatalystApp/Controller/Root.pm (ugly but necessary)
post('/token' => sub {
       my $c = shift;
       my $grant_type    = $c->param('grant_type');
       my $client_id     = $c->param('client_id');
       my $client_secret = $c->param('client_secret');



( run in 0.299 second using v1.01-cache-2.11-cpan-b61123c0432 )