Mojo-SAML
view release on metacpan or search on metacpan
lib/Mojolicious/Plugin/SAML.pm view on Meta::CPAN
package Mojolicious::Plugin::SAML;
use Mojo::Base 'Mojolicious::Plugin';
use Carp ();
use Crypt::OpenSSL::RSA;
use Crypt::OpenSSL::X509;
use Mojo::File 'path';
use Mojo::SAML ':docs';
use Mojo::SAML::IdP;
use Mojo::URL;
use Mojo::Util;
use Scalar::Util ();
has [qw/metadata route/];
sub sp_metadata {
my $plugin = shift;
#TODO this should search for an SPSSODescriptor
return $plugin->metadata->descriptors->[0];
}
sub register {
my ($plugin, $app, $conf) = @_;
$conf ||= {};
$conf = { %$conf, %{$app->config->{SAML}} };
Carp::croak 'No SAML configuration given'
unless keys %$conf;
my $login = $conf->{handle_login} // Carp::croak 'handle_login is required';
my $key = Crypt::OpenSSL::RSA->new_private_key(path($conf->{key})->slurp);
my $cert = Crypt::OpenSSL::X509->new_from_string(path($conf->{cert})->slurp);
my $idp = Mojo::SAML::IdP->new->from($conf->{idp});
my $location = $conf->{location};
my $entity_id = $conf->{entity_id} // $location;
my $key_info = KeyInfo->new(cert => $cert);
my $key_desc = KeyDescriptor->new(
key_info => $key_info,
use => 'signing',
);
my $post = AssertionConsumerService->new(
index => 0,
binding => 'HTTP-POST',
location => $location,
);
my $redir = AssertionConsumerService->new(
index => 1,
binding => 'HTTP-Redirect',
location => $location,
);
my $sp = SPSSODescriptor->new(
key_descriptors => [$key_desc],
assertion_consumer_services => [$post, $redir],
nameid_format => [qw/unspecified/],
);
my $metadata = EntityDescriptor->new(
id => 'MOJOSAML_METADATA',
entity_id => $entity_id,
descriptors => [$sp],
insert_signature => Signature->new(key_info => $key_info),
insert_xml_declaration => 1,
sign_with_key => $key,
);
$plugin->metadata($metadata);
$app->helper('saml.authn_request' => sub {
my ($c, %opt) = @_;
my $binding = $opt{binding} // 'HTTP-Redirect';
my $passive = $opt{passive} // 0;
# TODO get "sign" default from idp
my $sign = $opt{sign} // 1;
my $url = $idp->location_for(SingleSignOnService => $binding);
my $req = AuthnRequest->new(
issuer => $entity_id,
assertion_consumer_service_index => 0,
is_passive => $passive,
nameid_policy => NameIDPolicy->new(format => 'unspecified'),
destination => "$url",
);
if ($binding eq 'HTTP-Redirect') {
$url->query(SAMLRequest => $req->to_string_deflate);
if ($sign) {
$url->query({SigAlg => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'});
$key->use_sha256_hash;
my $val = $url->query->to_string;
( run in 2.750 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )