Net-SAML2
view release on metacpan or search on metacpan
lib/Net/SAML2/Binding/SOAP.pm view on Meta::CPAN
my ($self, $request) = @_;
my $saml = _get_saml_from_soap($request);
my @errors;
if (defined $saml) {
foreach my $cert (@{$self->idp_cert}) {
my $success = try {
$self->verify_xml(
$saml,
cert_text => $cert,
cacert => $self->cacert
);
return 1;
}
catch { push (@errors, $_); return 0; };
return $saml if $success;
}
if (@errors) {
croak "Unable to verify XML with the given certificates: "
. join(", ", @errors);
}
}
return;
}
sub _get_saml_from_soap {
my $soap = shift;
my $dom = no_comments($soap);
my $parser = XML::LibXML::XPathContext->new($dom);
$parser->registerNs('soap-env', 'http://schemas.xmlsoap.org/soap/envelope/');
$parser->registerNs('samlp', 'urn:oasis:names:tc:SAML:2.0:protocol');
my $set = $parser->findnodes('/soap-env:Envelope/soap-env:Body/*');
if ($set->size) {
return $set->get_node(1)->toString();
}
return;
}
sub create_soap_envelope {
my ($self, $message) = @_;
# sign the message
my $sig = Net::SAML2::XML::Sig->new({
x509 => 1,
key => $self->key,
cert => $self->cert,
exclusive => 1,
no_xml_declaration => 1,
});
my $signed_message = $sig->sign($message);
# OpenSSO ArtifactResolve hack
#
# OpenSSO's ArtifactResolve parser is completely hateful. It demands that
# the order of child elements in an ArtifactResolve message be:
#
# 1: saml:Issuer
# 2: dsig:Signature
# 3: samlp:Artifact
#
# Really.
#
if ($signed_message =~ /ArtifactResolve/) {
$signed_message =~ s!(<dsig:Signature.*?</dsig:Signature>)!!s;
my $signature = $1;
$signed_message =~ s/(<\/saml:Issuer>)/$1$signature/;
}
# test verify
my $ret = $sig->verify($signed_message);
die "failed to sign" unless $ret;
my $soap = <<"SOAP";
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body>$signed_message</SOAP-ENV:Body></SOAP-ENV:Envelope>
SOAP
return $soap;
}
__PACKAGE__->meta->make_immutable;
__END__
=pod
=encoding UTF-8
=head1 NAME
Net::SAML2::Binding::SOAP - SOAP binding for SAML
=head1 VERSION
version 0.85
=head1 SYNOPSIS
my $soap = Net::SAML2::Binding::SOAP->new(
url => $idp_url,
key => $key,
cert => $cert,
idp_cert => $idp_cert,
);
my $response = $soap->request($req);
Note that LWP::UserAgent maybe used which means that environment variables
may affect the use of https see:
=over
=item * L<PERL_LWP_SSL_CA_FILE and HTTPS_CA_FILE|https://metacpan.org/pod/LWP::UserAgent#SSL_ca_file-=%3E-$path>
=item * L<PERL_LWP_SSL_CA_PATH and HTTPS_CA_DIR|https://metacpan.org/pod/LWP::UserAgent#SSL_ca_path-=%3E-$path>
=back
=head1 METHODS
=head2 new( ... )
Constructor. Returns an instance of the SOAP binding configured for
the given IdP service url.
Arguments:
( run in 0.991 second using v1.01-cache-2.11-cpan-5a3173703d6 )