Net-SPID
view release on metacpan or search on metacpan
lib/Net/SPID/SAML.pm view on Meta::CPAN
package Net::SPID::SAML;
$Net::SPID::SAML::VERSION = '0.15';
use Moo;
use Carp;
use Crypt::OpenSSL::RSA;
use Crypt::OpenSSL::X509;
use File::Slurp qw(read_file);
use MIME::Base64 qw(decode_base64);
use Net::SPID::SAML::IdP;
use Net::SPID::SAML::In::LogoutRequest;
use Net::SPID::SAML::In::LogoutResponse;
use Net::SPID::SAML::In::Response;
use Net::SPID::SAML::Out::AuthnRequest;
use Net::SPID::SAML::Out::LogoutRequest;
use Net::SPID::SAML::Out::LogoutResponse;
use URI::Escape qw(uri_escape);
use XML::Writer;
has 'sp_entityid' => (is => 'ro', required => 1);
has 'sp_key_file' => (is => 'ro', required => 1);
has 'sp_cert_file' => (is => 'ro', required => 1);
has 'sp_key' => (is => 'lazy');
has 'sp_cert' => (is => 'lazy');
has 'sp_assertionconsumerservice' => (is => 'ro', required => 1);
has 'sp_singlelogoutservice' => (is => 'ro', required => 1);
has 'sp_attributeconsumingservice' => (is => 'ro', default => sub {[]});
has '_idp' => (is => 'ro', default => sub { {} });
extends 'Net::SPID';
sub _build_sp_key {
my ($self) = @_;
my $key_string = read_file($self->sp_key_file);
my $key = Crypt::OpenSSL::RSA->new_private_key($key_string);
$key->use_sha256_hash;
return $key;
}
sub _build_sp_cert {
my ($self) = @_;
return Crypt::OpenSSL::X509->new_from_file($self->sp_cert_file);
}
# TODO: generate the actual SPID button.
sub get_button {
my ($self, $url_cb) = @_;
# If $url_cb is a sprintf pattern, turn it into a callback.
if (!ref $url_cb) {
my $pattern = $url_cb;
$url_cb = sub {
sprintf $pattern, uri_escape(shift);
};
}
my $html = '';
foreach my $idp_id (sort keys %{$self->_idp}) {
$html .= sprintf qq!<p><a class="btn btn-primary" href="%s">Login with SPID</a> <small>(%s)</small></p>\n!,
$url_cb->($idp_id), $idp_id;
}
return $html;
}
sub load_idp_metadata {
my ($self, $dir) = @_;
$self->load_idp_from_xml_file($_) for glob "$dir/*.xml";
}
sub load_idp_from_xml_file {
my ($self, $xml_file) = @_;
# slurp XML from file
my $xml = do { local $/ = undef; open my $fh, '<', $xml_file; scalar <$fh> };
return $self->load_idp_from_xml($xml);
}
sub load_idp_from_xml {
my ($self, $xml) = @_;
my $idp = Net::SPID::SAML::IdP->new_from_xml(
_spid => $self,
xml => $xml,
);
$self->_idp->{$idp->entityID} = $idp;
return 1;
}
sub idps {
my ($self) = @_;
( run in 1.772 second using v1.01-cache-2.11-cpan-39bf76dae61 )