Net-SPID
view release on metacpan or search on metacpan
example/idp_metadata/spid-testenv-identityserver.xml view on Meta::CPAN
<?xml version="1.0" encoding="UTF-8"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_2487e8a5-3a05-488c-8fa6-fe32b8ae96c8" entityID="https://spid-testenv-identityserver:9443/samlsso">
<!-- Per test non viene richiesta la firma del metadata come avverrebbe in produzione -->
<IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<!-- certificato di default dell'identity server, se modificato è necessario cambiarlo -->
<X509Certificate>
MIICNTCCAZ6gAwIBAgIES343gjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJVUzELMAkGA1UE
CAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxDTALBgNVBAoMBFdTTzIxEjAQBgNVBAMMCWxv
Y2FsaG9zdDAeFw0xMDAyMTkwNzAyMjZaFw0zNTAyMTMwNzAyMjZaMFUxCzAJBgNVBAYTAlVTMQsw
CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzENMAsGA1UECgwEV1NPMjESMBAGA1UE
AwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUp/oV1vWc8/TkQSiAvTou
sMzOM4asB2iltr2QKozni5aVFu818MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe0hseUdN5
HpwvnH/DW8ZccGvk53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXnRS4HrKGJTzxaCcU7OQID
example/idp_metadata/spid-testenv2.xml view on Meta::CPAN
<?xml version='1.0' encoding='UTF-8'?>
<ns0:EntityDescriptor xmlns:ns0="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ns1="http://www.w3.org/2000/09/xmldsig#" entityID="http://localhost:8088"><ns0:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:t...
VDENMAsGA1UEBwwEUm9tYTAeFw0xODA2MjYxMDM5MzBaFw0xOTA2MjYxMDM5MzBa
MBwxCzAJBgNVBAYTAklUMQ0wCwYDVQQHDARSb21hMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAudciVxyXnPvTt2r8+3wE9DsibXu9fZwHjji0rOE7FJj8
fm/2rE0/GfDNyymGv7LHx9vKO8p1Ot4cl0ou/bR70PtJW9tM2ssyWPmHQXmBX84F
B/IuuOitABEtc3/HsWOyAA23XanCGpv6j6CW8TRjO+bi7nQnW3y/rLuCoTkBihH4
QGA0bkg8he56BSa3sAPnyO3VLavlYv3yYCQDqR+r2UM1f8gNPTlE5UIQzOYPXv1w
/YrrFhEx7xUYPh1J2e4J6xRRbZqzvB74QF0t0A0XueCITXLuVQ5eQ1rIWFAL1nwM
qWvep+3HvDpq0K8nzGFjnut6ElfyyhPp8+/H0zBOkQIDAQABMA0GCSqGSIb3DQEB
CwUAA4IBAQBw4mfH+WtR/etTVWK1Jy9DXWxAazFViQcVBualTuleRSHZjCv/nyv4
YbyFlTNarDI+LF+iG2rCABxgY40L6FpN9Gnsa5wijuKs0E6ZAvJ/rYfrYkE8wd0y
lib/Net/SPID/SAML.pm view on Meta::CPAN
# Validate request. This will throw an exception in case of failure.
$r->validate;
return $r;
}
sub metadata {
my ($self) = @_;
my $md = 'urn:oasis:names:tc:SAML:2.0:metadata';
my $dsig = 'http://www.w3.org/2000/09/xmldsig#';
my $x = XML::Writer->new(
OUTPUT => 'self',
NAMESPACES => 1,
PREFIX_MAP => {
$md => 'md',
$dsig => 'ds',
},
);
my $ID = $self->sp_entityid;
$ID =~ s/[^a-z0-9_-]/_/g;
$x->startTag([$md, 'EntityDescriptor'],
entityID => $self->sp_entityid,
ID => $ID);
$x->startTag([$md, 'SPSSODescriptor'],
protocolSupportEnumeration => 'urn:oasis:names:tc:SAML:2.0:protocol',
AuthnRequestsSigned => 'true',
WantAssertionsSigned => 'true');
{
$x->startTag([$md, 'KeyDescriptor'], use => 'signing');
$x->startTag([$dsig, 'KeyInfo']);
$x->startTag([$dsig, 'X509Data']);
my $cert = $self->sp_cert->as_string;
$cert =~ s/^-+BEGIN CERTIFICATE-+\n//;
$cert =~ s/\n-+END CERTIFICATE-+\n?//;
$x->dataElement([$dsig, 'X509Certificate'], $cert);
$x->endTag(); #ds:X509Data
$x->endTag(); #ds:KeyInfo
$x->endTag(); #KeyDescriptor
}
$x->dataElement([$md, 'NameIDFormat'],
'urn:oasis:names:tc:SAML:2.0:nameid-format:transient');
foreach my $acs_index (0..$#{$self->sp_assertionconsumerservice}) {
$x->emptyTag([$md, 'SingleSignOnService'],
lib/Net/SPID/SAML/IdP.pm view on Meta::CPAN
use Carp;
use Crypt::OpenSSL::X509;
use Mojo::XMLSig;
use XML::XPath;
sub new_from_xml {
my ($class, %args) = @_;
my $xpath = XML::XPath->new(xml => $args{xml});
$xpath->set_namespace('md', 'urn:oasis:names:tc:SAML:2.0:metadata');
$xpath->set_namespace('ds', 'http://www.w3.org/2000/09/xmldsig#');
if ($xpath->findnodes('/md:EntityDescriptor/dsig:Signature')->size > 0) {
# TODO: validate certificate against a known CA
Mojo::XMLSig::verify($args{xml})
or croak "Signature verification failed";
}
$args{entityID} = $xpath->findvalue('/md:EntityDescriptor/@entityID')->value;
$args{sso_urls} //= {};
for my $sso ($xpath->findnodes('/md:EntityDescriptor/md:IDPSSODescriptor/md:SingleSignOnService')){
my $binding = $sso->getAttribute('Binding');
lib/Net/SPID/SAML/In/Base.pm view on Meta::CPAN
print STDERR $self->xml;
}
sub _build_xpath {
my ($self) = @_;
my $xpath = XML::XPath->new(xml => $self->xml);
$xpath->set_namespace('saml', 'urn:oasis:names:tc:SAML:2.0:assertion');
$xpath->set_namespace('samlp', 'urn:oasis:names:tc:SAML:2.0:protocol');
$xpath->set_namespace('dsig', 'http://www.w3.org/2000/09/xmldsig#');
return $xpath;
}
sub validate {
my ($self, %args) = @_;
my $xpath = $self->xpath;
# detect IdP
my $idp = $self->_idp($self->_spid->get_idp($self->Issuer))
or croak "Unknown Issuer: " . $self->Issuer;
return 1;
}
sub _validate_post_or_redirect {
my ($self) = @_;
my $xpath = $self->xpath;
if ($xpath->findnodes('/*/dsig:Signature')->size > 0) {
# message is signed, it's HTTP-POST
my $pubkey = Crypt::OpenSSL::RSA->new_public_key($self->_idp->cert->pubkey);
Mojo::XMLSig::verify($self->xml, $pubkey)
or croak "Signature verification failed";
} elsif ($self->url) {
# this is supposed to be a HTTP-Redirect binding
my $u = URI->new($self->url);
# verify the response
my $SigAlg = $u->query_param('SigAlg');
my $pubkey = Crypt::OpenSSL::RSA->new_public_key($self->_idp->cert->pubkey);
if ($SigAlg eq 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256') {
$pubkey->use_sha256_hash;
} elsif ($SigAlg eq 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384') {
$pubkey->use_sha384_hash;
} elsif ($SigAlg eq 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512') {
$pubkey->use_sha512_hash;
} else {
croak "Unsupported SigAlg: $SigAlg";
}
my $sig = decode_base64($u->query_param_delete('Signature'));
$pubkey->verify($u->query, $sig)
or croak "Signature verification failed";
return 1;
lib/Net/SPID/SAML/In/Response.pm view on Meta::CPAN
$self->Assertion_InResponseTo, $args{in_response_to}
if $self->Assertion_InResponseTo ne $args{in_response_to};
# this validates all the signatures in the given XML, and requires that at least one exists
my $pubkey = Crypt::OpenSSL::RSA->new_public_key($self->_idp->cert->pubkey);
Mojo::XMLSig::verify($self->xml, $pubkey)
or croak "Signature verification failed";
# SPID regulations require that Assertion is signed, while Response can be not signed
croak "Response/Assertion is not signed"
if $xpath->findnodes('/samlp:Response/saml:Assertion/dsig:Signature')->size == 0;
my $now = DateTime->now;
# exact match is ok
croak sprintf "Invalid NotBefore: '%s' (now: '%s')",
$self->NotBefore->iso8601, $now->iso8601
if DateTime->compare($now, $self->NotBefore) < 0;
# exact match is *not* ok
croak sprintf "Invalid NotOnOrAfter: '%s' (now: '%s')",
lib/Net/SPID/SAML/Out/Base.pm view on Meta::CPAN
sub _signature_template {
my ($self, $ref) = @_;
my $cert = $self->_spid->sp_cert->as_string;
$cert =~ s/^-+BEGIN CERTIFICATE-+\n//;
$cert =~ s/\n-+END CERTIFICATE-+\n?//;
# TODO: replace this with XML::Writer calls in order to disable UNSAFE?
return <<"EOF"
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#$ref">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue></ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue></ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>$cert</ds:X509Certificate>
lib/Net/SPID/SAML/Out/Base.pm view on Meta::CPAN
my $xml = $self->xml(binding => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect');
print STDERR $xml, "\n";
my $payload = '';
rawdeflate \$xml => \$payload;
$payload = encode_base64($payload, '');
my $u = URI->new($url);
$u->query_param($args{param}, $payload);
$u->query_param('RelayState', $args{relaystate}) if defined $args{relaystate};
$u->query_param('SigAlg', 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256');
my $sig = encode_base64($self->_spid->sp_key->sign($u->query), '');
$u->query_param('Signature', $sig);
return $u->as_string;
}
sub post_form {
my ($self, $url, %args) = @_;
( run in 0.798 second using v1.01-cache-2.11-cpan-71847e10f99 )