1- use strict;
2- use warnings;
31package Net::SAML2::Binding::SOAP ;
2+ use Moose;
3+
44# VERSION
55
6- use Moose;
76use MooseX::Types::URI qw/ Uri / ;
87use Net::SAML2::XML::Util qw/ no_comments / ;
8+ use Carp qw( croak) ;
9+
10+ with ' Net::SAML2::Role::VerifyXML' ;
911
10- # ABSTRACT: Net::SAML2::Binding::Artifact - SOAP binding for SAML
12+ # ABSTRACT: Net::SAML2::Binding::SOAP - SOAP binding for SAML
1113
1214=head1 NAME
1315
14- Net::SAML2::Binding::Artifact - SOAP binding for SAML2
16+ Net::SAML2::Binding::SOAP - SOAP binding for SAML2
1517
1618=head1 SYNOPSIS
1719
@@ -93,7 +95,18 @@ has 'url' => (isa => Uri, is => 'ro', required => 1, coerce => 1);
9395has ' key' => (isa => ' Str' , is => ' ro' , required => 1);
9496has ' cert' => (isa => ' Str' , is => ' ro' , required => 1);
9597has ' idp_cert' => (isa => ' Str' , is => ' ro' , required => 1);
96- has ' cacert' => (isa => ' Str' , is => ' ro' , required => 1);
98+ has ' cacert' => (
99+ is => ' ro' ,
100+ isa => ' Str' ,
101+ required => 0,
102+ predicate => ' has_cacert'
103+ );
104+ has ' anchors' => (
105+ is => ' ro' ,
106+ isa => ' HashRef' ,
107+ required => 0,
108+ predicate => ' has_anchors'
109+ );
97110
98111=head2 request( $message )
99112
@@ -142,35 +155,16 @@ Accepts a string containing the complete SOAP response.
142155sub handle_response {
143156 my ($self , $response ) = @_ ;
144157
145- # verify the response
146- my $x = Net::SAML2::XML::Sig-> new(
147- {
148- x509 => 1,
149- cert_text => $self -> idp_cert,
150- exclusive => 1,
158+ my $saml = _get_saml_from_soap($response );
159+ $self -> verify_xml(
160+ $saml ,
151161 no_xml_declaration => 1,
152- });
153-
154- my $ret = $x -> verify($response );
155- die " bad SOAP response" unless $ret ;
156-
157- # verify the signing certificate
158- my $cert = $x -> signer_cert;
159- my $ca = Crypt::OpenSSL::Verify-> new($self -> cacert, { strict_certs => 0, });
160- $ret = $ca -> verify($cert );
161- die " bad signer cert" unless $ret ;
162-
163- my $subject = sprintf (" %s (verified)" , $cert -> subject);
162+ cert_text => $self -> idp_cert,
163+ cacert => $self -> cacert,
164+ anchors => $self -> anchors
165+ );
166+ return $saml ;
164167
165- # parse the SOAP response and return the payload
166- my $dom = no_comments($response );
167-
168- my $parser = XML::LibXML::XPathContext-> new($dom );
169- $parser -> registerNs(' soap-env' , ' http://schemas.xmlsoap.org/soap/envelope/' );
170- $parser -> registerNs(' samlp' , ' urn:oasis:names:tc:SAML:2.0:protocol' );
171-
172- my $saml = $parser -> findnodes_as_string(' /soap-env:Envelope/soap-env:Body/*' );
173- return ($subject , $saml );
174168}
175169
176170=head2 handle_request( $request )
@@ -184,29 +178,29 @@ Accepts a string containing the complete SOAP request.
184178sub handle_request {
185179 my ($self , $request ) = @_ ;
186180
187- my $dom = no_comments($request );
181+ my $saml = _get_saml_from_soap($request );
182+ if (defined $saml ) {
183+ $self -> verify_xml(
184+ $saml ,
185+ cert_text => $self -> idp_cert,
186+ cacert => $self -> cacert
187+ );
188+ return $saml ;
189+ }
190+
191+ return ;
192+ }
188193
194+ sub _get_saml_from_soap {
195+ my $soap = shift ;
196+ my $dom = no_comments($soap );
189197 my $parser = XML::LibXML::XPathContext-> new($dom );
190198 $parser -> registerNs(' soap-env' , ' http://schemas.xmlsoap.org/soap/envelope/' );
191199 $parser -> registerNs(' samlp' , ' urn:oasis:names:tc:SAML:2.0:protocol' );
192-
193- my ($nodes ) = $parser -> findnodes(' /soap-env:Envelope/soap-env:Body/*' );
194- my $saml = $nodes -> toString;
195-
196- if (defined $saml ) {
197- my $x = Net::SAML2::XML::Sig-> new({ x509 => 1, cert_text => $self -> idp_cert, exclusive => 1, });
198- my $ret = $x -> verify($saml );
199- die " bad signature" unless $ret ;
200-
201- my $cert = $x -> signer_cert;
202- my $ca = Crypt::OpenSSL::Verify-> new($self -> cacert, { strict_certs => 0, });
203- $ret = $ca -> verify($cert );
204- die " bad certificate in request: " .$cert -> subject unless $ret ;
205-
206- my $subject = $cert -> subject;
207- return ($subject , $saml );
200+ my $set = $parser -> findnodes(' /soap-env:Envelope/soap-env:Body/*' );
201+ if ($set -> size) {
202+ return $set -> get_node(1)-> toString();
208203 }
209-
210204 return ;
211205}
212206
0 commit comments