File Coverage

blib/lib/Net/SAML2/Binding/POST.pm
Criterion Covered Total %
statement 41 41 100.0
branch 4 8 50.0
condition n/a
subroutine 11 11 100.0
pod 2 2 100.0
total 58 62 93.5


line stmt bran cond sub pod time code
1 26     26   203 use strict;
  26         62  
  26         858  
2 26     26   154 use warnings;
  26         62  
  26         1385  
3             package Net::SAML2::Binding::POST;
4             our $VERSION = '0.74'; # VERSION
5              
6 26     26   200 use Moose;
  26         58  
  26         183  
7 26     26   170873 use Carp qw(croak);
  26         71  
  26         1476  
8              
9             # ABSTRACT: HTTP POST binding for SAML
10              
11              
12 26     26   12159 use Net::SAML2::XML::Sig;
  26         91  
  26         289  
13 26     26   1562 use MIME::Base64 qw/ decode_base64 /;
  26         59  
  26         1463  
14 26     26   11056 use Crypt::OpenSSL::Verify;
  26         18655  
  26         829  
15 26     26   189 use MIME::Base64;
  26         59  
  26         1305  
16 26     26   177 use URI::Escape;
  26         56  
  26         10541  
17              
18             with 'Net::SAML2::Role::VerifyXML';
19              
20              
21             has 'cert_text' => (isa => 'Str', is => 'ro');
22             has 'cacert' => (isa => 'Maybe[Str]', is => 'ro');
23              
24             has 'cert' => (isa => 'Str', is => 'ro', required => 0, predicate => 'has_cert');
25             has 'key' => (isa => 'Str', is => 'ro', required => 0, predicate => 'has_key');
26              
27              
28             sub handle_response {
29 3     3 1 879 my ($self, $response) = @_;
30              
31             # unpack and check the signature
32 3         137 my $xml = decode_base64($response);
33              
34 3 50       111 $self->verify_xml(
    50          
35             $xml,
36             no_xml_declaration => 1,
37             $self->cert_text ? (
38             cert_text => $self->cert_text
39             ) : (),
40             $self->cacert ? (
41             cacert => $self->cacert
42             ) : (),
43              
44             );
45 3         44 return $xml;
46             }
47              
48              
49             sub sign_xml {
50 3     3 1 455 my ($self, $request) = @_;
51              
52 3 50       121 croak("Need to have a cert specified") unless $self->has_cert;
53 3 50       111 croak("Need to have a key specified") unless $self->has_key;
54              
55 3         93 my $signer = XML::Sig->new({
56             key => $self->key,
57             cert => $self->cert,
58             no_xml_declaration => 1,
59             }
60             );
61              
62 3         2999 my $signed_message = $signer->sign($request);
63              
64             # saml-schema-protocol-2.0.xsd Schema hack
65             #
66             # The real fix here is to fix XML::Sig to accept a XPATH to
67             # place the signature in the correct location. Or use XML::LibXML
68             # here to do so
69             #
70             # The protocol schema defines a sequence which requires the order
71             # of the child elements in a Protocol based message:
72             #
73             # The dsig:Signature (should it exist) MUST follow the saml:Issuer
74             #
75             # 1: saml:Issuer
76             # 2: dsig:Signature
77             #
78             # Seems like an oversight in the SAML schema specifiation but...
79              
80 3         7790 $signed_message =~ s!(<dsig:Signature.*?</dsig:Signature>)!!s;
81 3         17 my $signature = $1;
82 3         49 $signed_message =~ s/(<\/saml\d*:Issuer>)/$1$signature/;
83              
84 3         62 my $encoded_request = encode_base64($signed_message, "\n");
85              
86 3         167 return $encoded_request;
87              
88             }
89             __PACKAGE__->meta->make_immutable;
90              
91             __END__
92              
93             =pod
94              
95             =encoding UTF-8
96              
97             =head1 NAME
98              
99             Net::SAML2::Binding::POST - HTTP POST binding for SAML
100              
101             =head1 VERSION
102              
103             version 0.74
104              
105             =head1 SYNOPSIS
106              
107             my $post = Net::SAML2::Binding::POST->new(
108             cacert => '/path/to/ca-cert.pem'
109             );
110             my $xml = $post->handle_response(
111             $saml_response
112             );
113              
114             =head1 NAME
115              
116             Net::SAML2::Binding::POST - HTTP POST binding for SAML2
117              
118             =head1 METHODS
119              
120             =head2 new( )
121              
122             Constructor. Returns an instance of the POST binding.
123              
124             Arguments:
125              
126             =over
127              
128             =item B<cacert>
129              
130             path to the CA certificate for verification
131              
132             =back
133              
134             =head2 handle_response( $response )
135              
136             my $xml = $self->handle_response($response);
137              
138             Decodes and verifies the Base64-encoded SAMLResponse CGI parameter.
139             Returns the decoded response as XML.
140              
141             =head2 sign_xml( $request )
142              
143             Sign and encode the SAMLRequest.
144              
145             =head1 AUTHORS
146              
147             =over 4
148              
149             =item *
150              
151             Chris Andrews <chrisa@cpan.org>
152              
153             =item *
154              
155             Timothy Legge <timlegge@gmail.com>
156              
157             =back
158              
159             =head1 COPYRIGHT AND LICENSE
160              
161             This software is copyright (c) 2023 by Venda Ltd, see the CONTRIBUTORS file for others.
162              
163             This is free software; you can redistribute it and/or modify it under
164             the same terms as the Perl 5 programming language system itself.
165              
166             =cut