Skip to content

Commit d8ca5b9

Browse files
authored
Merge pull request #156 from timlegge/artifact_object
Create a Artifact to hold the parts of the Artifact
2 parents b9f50e8 + 3c9e4fc commit d8ca5b9

File tree

4 files changed

+326
-8
lines changed

4 files changed

+326
-8
lines changed

lib/Net/SAML2.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use Net::SAML2::Protocol::AuthnRequest;
2121
use Net::SAML2::Protocol::LogoutRequest;
2222
use Net::SAML2::Protocol::LogoutResponse;;
2323
use Net::SAML2::Protocol::Assertion;
24+
use Net::SAML2::Protocol::Artifact;
2425
use Net::SAML2::Protocol::ArtifactResolve;
2526

2627
1;

lib/Net/SAML2/Protocol/Artifact.pm

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
use strict;
2+
use warnings;
3+
package Net::SAML2::Protocol::Artifact;
4+
# VERSION
5+
6+
use Moose;
7+
use MooseX::Types::DateTime qw/ DateTime /;
8+
use DateTime::Format::XSD;
9+
use Net::SAML2::XML::Util qw/ no_comments /;
10+
use XML::LibXML;
11+
12+
with 'Net::SAML2::Role::ProtocolMessage';
13+
14+
# ABSTRACT: Net::SAML2::Protocol::Artifact - SAML2 artifact object
15+
16+
=head1 NAME
17+
18+
Net::SAML2::Protocol::Artifact - SAML2 artifact object
19+
20+
=head1 SYNOPSIS
21+
22+
my $artifact = Net::SAML2::Protocol::Artifact->new_from_xml(
23+
xml => Net::SAML2::Binding::SOAP->request(
24+
Net::SAML2::SP->artifact_request(
25+
$art_url,
26+
$artifact
27+
)->as_xml)
28+
);
29+
30+
or
31+
32+
my $request = Net::SAML2::SP->artifact_request($art_url, $artifact)->as_xml;
33+
my soap_response = Net::SAML2::Binding::SOAP->request($request);
34+
my $artifact = Net::SAML2::Protocol::Artifact->new_from_xml(soap_response);
35+
36+
# get_response returns the Response or LogoutResponse
37+
my art_response = $artifact->get_response();
38+
39+
=cut
40+
41+
has 'issue_instant' => (isa => DateTime, is => 'ro', required => 1);
42+
has 'in_response_to' => (isa => 'Str', is => 'ro', required => 1);
43+
has 'issuer' => (isa => 'Str', is => 'ro', required => 1);
44+
has 'status' => (isa => 'Str', is => 'ro', required => 1);
45+
has 'logoutresponse_object' => (
46+
isa => 'XML::LibXML::Element',
47+
is => 'ro',
48+
required => 0,
49+
init_arg => 'logout_response',
50+
predicate => 'has_logout_response'
51+
);
52+
has 'response_object' => (
53+
isa => 'XML::LibXML::Element',
54+
is => 'ro',
55+
required => 0,
56+
init_arg => 'response',
57+
predicate => 'has_response'
58+
);
59+
60+
=head1 METHODS
61+
62+
=cut
63+
64+
=head2 new_from_xml( ... )
65+
66+
Constructor. Creates an instance of the Artifact object, parsing the
67+
given XML to find the response and logout_response should they exist as
68+
well as the issuer, issue_instant and in_response_to.
69+
70+
Arguments:
71+
72+
=over
73+
74+
=item B<xml>
75+
76+
XML data
77+
78+
=back
79+
80+
=cut
81+
82+
sub new_from_xml {
83+
my($class, %args) = @_;
84+
85+
my $dom = no_comments($args{xml});
86+
my $key_file = $args{key_file};
87+
my $cacert = $args{cacert};
88+
89+
my $xpath = XML::LibXML::XPathContext->new($dom);
90+
$xpath->registerNs('saml', 'urn:oasis:names:tc:SAML:2.0:assertion');
91+
$xpath->registerNs('samlp', 'urn:oasis:names:tc:SAML:2.0:protocol');
92+
93+
my $response;
94+
if (my $node = $xpath->findnodes('/samlp:ArtifactResponse/samlp:Response')) {
95+
$response = $node->get_node(1)->cloneNode( 1 );
96+
}
97+
my $logoutresponse;
98+
if (my $node = $xpath->findnodes('/samlp:ArtifactResponse/samlp:LogoutResponse')) {
99+
$logoutresponse = $node->get_node(1)->cloneNode( 1 );
100+
}
101+
102+
my $issue_instant;
103+
104+
if (my $value = $xpath->findvalue('/samlp:ArtifactResponse/@IssueInstant')) {
105+
$issue_instant = DateTime::Format::XSD->parse_datetime($value);
106+
}
107+
108+
my $self = $class->new(
109+
id => $xpath->findvalue('/samlp:ArtifactResponse/@ID'),
110+
in_response_to => $xpath->findvalue('/samlp:ArtifactResponse/@InResponseTo'),
111+
issue_instant => $issue_instant,
112+
issuer => $xpath->findvalue('/samlp:ArtifactResponse/saml:Issuer'),
113+
status => $xpath->findvalue('/samlp:ArtifactResponse/samlp:Status/samlp:StatusCode/@Value'),
114+
$response ? (response => $response) : (),
115+
$logoutresponse ? (logout_response => $logoutresponse) : (),
116+
);
117+
118+
return $self;
119+
}
120+
121+
=head2 response
122+
123+
Returns the response
124+
125+
=cut
126+
127+
sub response {
128+
my $self = shift;
129+
return $self->response_object->toString;
130+
}
131+
132+
=head2 logout_response
133+
134+
Returns the logoutresponse
135+
136+
=cut
137+
138+
sub logout_response {
139+
my $self = shift;
140+
return $self->logoutresponse_object->toString;
141+
}
142+
143+
=head2 success( )
144+
145+
Returns true if the Response's status is Success.
146+
147+
=cut
148+
149+
sub success {
150+
my ($self) = @_;
151+
return 1 if $self->status eq $self->status_uri('success');
152+
return 0;
153+
}
154+
155+
=head2 get_response ( )
156+
157+
Returns the LogoutResponse or Response depending on which is defined
158+
159+
=cut
160+
161+
sub get_response {
162+
my ($self) = @_;
163+
return $self->logout_response if $self->has_logout_response;
164+
return $self->response
165+
}
166+
167+
1;

t/21-artifact-response.t

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
use strict;
2+
use warnings;
3+
use Test::Lib;
4+
use Test::Net::SAML2;
5+
use Sub::Override;
6+
7+
use Net::SAML2::Protocol::LogoutResponse;
8+
use Net::SAML2::Protocol::Artifact;
9+
use Net::SAML2::Protocol::Assertion;
10+
use URN::OASIS::SAML2 qw(:urn);
11+
12+
my $artifact_assertion_response = << 'ASSERTION_RESPONSE';
13+
<samlp:ArtifactResponse xmlns="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="ID_78cb9be7-12e9-4457-990f-b0ab4fb63f9f" InResponseTo="NETSAML2_7aaf00ca8438e4906f65659a6dd7f84b8a19aca8dc0916ea7066d7e6ab19a62f" IssueInstant="2023-01-29T16:21:09.254Z" Version="2.0"><saml:Issuer>https://keycloak.local:8443/realms/Foswiki</saml:Issuer><dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:SignedInfo><dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><dsig:Reference URI="#ID_78cb9be7-12e9-4457-990f-b0ab4fb63f9f"><dsig:Transforms><dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><dsig:DigestValue>xa6Re6R1tZRL0O2I41E4F75+pPw=</dsig:DigestValue></dsig:Reference></dsig:SignedInfo><dsig:SignatureValue>fnVIbQFRtlLPVasc5oDCM6DsX4wbgta747bVFolx/APfzTYfP2n3MhZVOqSH1E6B6lzYOWsp1YOn&#13;
14+
ZKC4eQWtRMFui3jzHS3Py+L7Jj15z4sjP7wURLBhxAv4tkYxNK8BAka/JjaZOz1VbhcuYcSTzCCm&#13;
15+
ypJaSLWIQTj+SgCJvsX22vJ71q1pRgfcSeD2bAIEVdqqCvCBpMoRMoMzAMQchJ7yertoQso/9pAV&#13;
16+
LOu+fF4C1UARuKjzFdFT2tkUigW4LvAK4XaQzPRhHVjWO1z+t9XeA0qkMUMCMiSNzRSvQb3DB9XV&#13;
17+
tmjFOE3ajs92hg65EC7ByJ8ze+wk41c5ua0xEA==</dsig:SignatureValue><dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>MIICnTCCAYUCBgGEmFcmeDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdGb3N3aWtpMB4XDTIy&#13;
18+
MTEyMTAzNTczOVoXDTMyMTEyMTAzNTkxOVowEjEQMA4GA1UEAwwHRm9zd2lraTCCASIwDQYJKoZI&#13;
19+
hvcNAQEBBQADggEPADCCAQoCggEBAJeeWUPyhuxoA0S7tWF5eG18l5cSZYXjbH2eoa6bXNJB1h2L&#13;
20+
1Bmi5a14DVSPQETeUo/l9yzOdpp23ngCvROue0uwg4fNTqdOECOYjIgFuDTwRAtvFoKXZ1He8AD6&#13;
21+
OlgwP/k2ne85NxQ+rCt/bxrJ2b8J57J0FjphfHVJcgTZEu8fmahkO6sYYiURb65mVzR9I7Sq9W1t&#13;
22+
DGrCIup7h9kYi+xDcAjVreZboYqpiL/ElqJGYkp12PXfx/RFsswu7ICCjjIK7WyuqvSrdzW0vHgL&#13;
23+
ZmaVe+KzE80Ig3VAsO4lbCBs8JHS6CkmHc48kfiC2qmiBfE1WVA2tmiGSCo3URbg6VUCAwEAATAN&#13;
24+
BgkqhkiG9w0BAQsFAAOCAQEAbridXRbw3WeKUyeR8o5IzdEtO8j+vw6jCd2lBHLEi2sPpHhi6+Lj&#13;
25+
cQ+haqALCB2dknuBQHt3HBo/U9cRFBa5xA5z0Do06CsrZ2czks3icXYkCzVCOtCvbj/79Vo3JLoV&#13;
26+
ifX+rLEYlxhKVaVhFslwSoS59kFwuMAo73szhW0C8HLtWDN0yrS/XDw1Nidesx+AmDEr/K5ofgKa&#13;
27+
H/zExdQG7RcrAeHGswluWrEd43wLuX1UpIp6CLsrVSGwDQNCsgZATXbiyYS3RNhQeAW7hW9aJuG+&#13;
28+
tqFxJ4u+6crHsA/FLZ2XVquRHx5dClGa9i9aPaK6Q7V9fo9KpgCBCAShpBabNA==</dsig:X509Certificate></dsig:X509Data><dsig:KeyValue><dsig:RSAKeyValue><dsig:Modulus>l55ZQ/KG7GgDRLu1YXl4bXyXlxJlheNsfZ6hrptc0kHWHYvUGaLlrXgNVI9ARN5Sj+X3LM52mnbe&#13;
29+
eAK9E657S7CDh81Op04QI5iMiAW4NPBEC28WgpdnUd7wAPo6WDA/+Tad7zk3FD6sK39vGsnZvwnn&#13;
30+
snQWOmF8dUlyBNkS7x+ZqGQ7qxhiJRFvrmZXNH0jtKr1bW0MasIi6nuH2RiL7ENwCNWt5luhiqmI&#13;
31+
v8SWokZiSnXY9d/H9EWyzC7sgIKOMgrtbK6q9Kt3NbS8eAtmZpV74rMTzQiDdUCw7iVsIGzwkdLo&#13;
32+
KSYdzjyR+ILaqaIF8TVZUDa2aIZIKjdRFuDpVQ==</dsig:Modulus><dsig:Exponent>AQAB</dsig:Exponent></dsig:RSAKeyValue></dsig:KeyValue></dsig:KeyInfo></dsig:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><samlp:Response Destination="https://netsaml2-testapp.local/consumer-artifact" ID="ID_31872488-8064-45c7-bfc2-7fc6646f6793" InResponseTo="NETSAML2_2b2bcaa750d745ed5ffec2e3cc3a905ab855de0f7970d9391427641a720e6a97" IssueInstant="2023-01-29T16:21:09.253Z" Version="2.0"><saml:Issuer>https://keycloak.local:8443/realms/Foswiki</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><saml:Assertion ID="ID_ef9c4328-63de-4d55-ae05-e5342e67f36c" IssueInstant="2023-01-29T16:21:09.253Z" Version="2.0"><saml:Issuer>https://keycloak.local:8443/realms/Foswiki</saml:Issuer><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">timlegge@cpan.org</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="NETSAML2_2b2bcaa750d745ed5ffec2e3cc3a905ab855de0f7970d9391427641a720e6a97" NotOnOrAfter="2023-01-29T16:26:07.253Z" Recipient="https://netsaml2-testapp.local/consumer-artifact"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2023-01-29T16:21:07.253Z" NotOnOrAfter="2023-01-29T16:22:07.253Z"><saml:AudienceRestriction><saml:Audience>https://netsaml2-testapp.local</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2023-01-29T16:21:09.253Z" SessionIndex="bb763071-a7c7-45e4-a2a6-d69b1c06a001::29499342-7453-4345-b702-68351fcad4f2" SessionNotOnOrAfter="2023-01-30T02:21:09.253Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute FriendlyName="FirstName" Name="FirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Timothy</saml:AttributeValue></saml:Attribute><saml:Attribute FriendlyName="surname" Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Legge</saml:AttributeValue></saml:Attribute><saml:Attribute FriendlyName="CN" Name="CN" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">keycloak.local</saml:AttributeValue></saml:Attribute><saml:Attribute FriendlyName="email" Name="EmailAddress" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">timlegge@cpan.org</saml:AttributeValue></saml:Attribute><saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">manage-account-links</saml:AttributeValue></saml:Attribute><saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">default-roles-foswiki</saml:AttributeValue></saml:Attribute><saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">offline_access</saml:AttributeValue></saml:Attribute><saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">view-profile</saml:AttributeValue></saml:Attribute><saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">uma_authorization</saml:AttributeValue></saml:Attribute><saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">manage-account</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response></samlp:ArtifactResponse>
33+
ASSERTION_RESPONSE
34+
35+
my $artifact_logout_response = << 'LOGOUT_RESPONSE';
36+
<samlp:ArtifactResponse xmlns="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="ID_7dd3a831-57e9-409e-873e-eb4730ed8392" InResponseTo="NETSAML2_209c37a48a23919f6de933486f0a03d9e8f9ccd8789503c86b446a16c96d3ce4" IssueInstant="2023-01-29T15:59:45.462Z" Version="2.0"><saml:Issuer>https://keycloak.local:8443/realms/Foswiki</saml:Issuer><dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:SignedInfo><dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><dsig:Reference URI="#ID_7dd3a831-57e9-409e-873e-eb4730ed8392"><dsig:Transforms><dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><dsig:DigestValue>pba2nAP9gZUz930g5BqIIXJ+t68=</dsig:DigestValue></dsig:Reference></dsig:SignedInfo><dsig:SignatureValue>Mr2D/azy1FP9dXgLi7ycFzkhdVQup2sr7Qt1bmDcH5ja3JEMeMjHsjFzaYcYN/k2tPIxT0FzNvzU&#13;
37+
cClAeaHcn419fdNJXEX7dhcx36rLA4xKV8JHNuvjoKbb31D5DQAsE2YH4qqoy3SQr5FiLRfGdnTj&#13;
38+
6F0CN73BjecaoxgiV+5ajS5YwHHDirolRbHQdWVC6KFqlfpqSv743bbZhBThjVBxeyKCpmFaGnZM&#13;
39+
JM/UQbY7aPe1yqnbATvEcj+9N25Q7+RDNIxVnjXIq2FzNXE12PbUm/gMW1hBbGtH59CEvs0xOuB5&#13;
40+
v+kSGB6yVS3Odz5m4wFvtK4ABuLMQmKqDb3TXw==</dsig:SignatureValue><dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>MIICnTCCAYUCBgGEmFcmeDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdGb3N3aWtpMB4XDTIy&#13;
41+
MTEyMTAzNTczOVoXDTMyMTEyMTAzNTkxOVowEjEQMA4GA1UEAwwHRm9zd2lraTCCASIwDQYJKoZI&#13;
42+
hvcNAQEBBQADggEPADCCAQoCggEBAJeeWUPyhuxoA0S7tWF5eG18l5cSZYXjbH2eoa6bXNJB1h2L&#13;
43+
1Bmi5a14DVSPQETeUo/l9yzOdpp23ngCvROue0uwg4fNTqdOECOYjIgFuDTwRAtvFoKXZ1He8AD6&#13;
44+
OlgwP/k2ne85NxQ+rCt/bxrJ2b8J57J0FjphfHVJcgTZEu8fmahkO6sYYiURb65mVzR9I7Sq9W1t&#13;
45+
DGrCIup7h9kYi+xDcAjVreZboYqpiL/ElqJGYkp12PXfx/RFsswu7ICCjjIK7WyuqvSrdzW0vHgL&#13;
46+
ZmaVe+KzE80Ig3VAsO4lbCBs8JHS6CkmHc48kfiC2qmiBfE1WVA2tmiGSCo3URbg6VUCAwEAATAN&#13;
47+
BgkqhkiG9w0BAQsFAAOCAQEAbridXRbw3WeKUyeR8o5IzdEtO8j+vw6jCd2lBHLEi2sPpHhi6+Lj&#13;
48+
cQ+haqALCB2dknuBQHt3HBo/U9cRFBa5xA5z0Do06CsrZ2czks3icXYkCzVCOtCvbj/79Vo3JLoV&#13;
49+
ifX+rLEYlxhKVaVhFslwSoS59kFwuMAo73szhW0C8HLtWDN0yrS/XDw1Nidesx+AmDEr/K5ofgKa&#13;
50+
H/zExdQG7RcrAeHGswluWrEd43wLuX1UpIp6CLsrVSGwDQNCsgZATXbiyYS3RNhQeAW7hW9aJuG+&#13;
51+
tqFxJ4u+6crHsA/FLZ2XVquRHx5dClGa9i9aPaK6Q7V9fo9KpgCBCAShpBabNA==</dsig:X509Certificate></dsig:X509Data><dsig:KeyValue><dsig:RSAKeyValue><dsig:Modulus>l55ZQ/KG7GgDRLu1YXl4bXyXlxJlheNsfZ6hrptc0kHWHYvUGaLlrXgNVI9ARN5Sj+X3LM52mnbe&#13;
52+
eAK9E657S7CDh81Op04QI5iMiAW4NPBEC28WgpdnUd7wAPo6WDA/+Tad7zk3FD6sK39vGsnZvwnn&#13;
53+
snQWOmF8dUlyBNkS7x+ZqGQ7qxhiJRFvrmZXNH0jtKr1bW0MasIi6nuH2RiL7ENwCNWt5luhiqmI&#13;
54+
v8SWokZiSnXY9d/H9EWyzC7sgIKOMgrtbK6q9Kt3NbS8eAtmZpV74rMTzQiDdUCw7iVsIGzwkdLo&#13;
55+
KSYdzjyR+ILaqaIF8TVZUDa2aIZIKjdRFuDpVQ==</dsig:Modulus><dsig:Exponent>AQAB</dsig:Exponent></dsig:RSAKeyValue></dsig:KeyValue></dsig:KeyInfo></dsig:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><samlp:LogoutResponse Destination="https://netsaml2-testapp.local/sls-consumer-artifact" ID="ID_bfc25851-4da2-4420-8240-9103b77b12dc" InResponseTo="NETSAML2_0b499739aa1d76eb80093a068053b8fee62cade60f7dc27826d0f13b19cad16a" IssueInstant="2023-01-29T15:59:45.462Z" Version="2.0"><Issuer>https://keycloak.local:8443/realms/Foswiki</Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status></samlp:LogoutResponse></samlp:ArtifactResponse>
56+
LOGOUT_RESPONSE
57+
58+
my $override = Sub::Override->override(
59+
'Net::SAML2::Protocol::Assertion::valid' =>
60+
sub {
61+
my ($self, $audience, $in_response_to) = @_;
62+
63+
return 0 unless defined $audience;
64+
return 0 unless($audience eq $self->audience);
65+
66+
return 0 unless !defined $in_response_to
67+
or $in_response_to eq $self->in_response_to;
68+
69+
my $now = $self->not_before->add(seconds => 10);
70+
71+
# not_before is "NotBefore" element - exact match is ok
72+
# not_after is "NotOnOrAfter" element - exact match is *not* ok
73+
return 0 unless DateTime::->compare($now, $self->not_before) > -1;
74+
return 0 unless DateTime::->compare($self->not_after, $now) > 0;
75+
76+
return 1;
77+
}
78+
);
79+
80+
###################################
81+
# Assertion from ArtifactResponse #
82+
###################################
83+
my $assertion_artifact = Net::SAML2::Protocol::Artifact->new_from_xml(
84+
xml => $artifact_assertion_response,
85+
);
86+
87+
isa_ok($assertion_artifact, "Net::SAML2::Protocol::Artifact");
88+
89+
my $assertion = Net::SAML2::Protocol::Assertion->new_from_xml(
90+
xml => $assertion_artifact->response,
91+
);
92+
93+
isa_ok($assertion, "Net::SAML2::Protocol::Assertion");
94+
95+
is($assertion->valid("https://netsaml2-testapp.local"), "1", "Assertion is Valid - ok");
96+
97+
is($assertion->{in_response_to}, 'NETSAML2_2b2bcaa750d745ed5ffec2e3cc3a905ab855de0f7970d9391427641a720e6a97', "Assertion InResponseTo - ok");
98+
99+
is($assertion->{id}, 'ID_ef9c4328-63de-4d55-ae05-e5342e67f36c', "Assertion ID - ok");
100+
101+
$assertion = Net::SAML2::Protocol::Assertion->new_from_xml(
102+
xml => $assertion_artifact->get_response(),
103+
);
104+
105+
isa_ok($assertion, "Net::SAML2::Protocol::Assertion", "from get_response");
106+
107+
is($assertion->valid("https://netsaml2-testapp.local"), "1", "Assertion is Valid - ok");
108+
109+
is($assertion->{in_response_to}, 'NETSAML2_2b2bcaa750d745ed5ffec2e3cc3a905ab855de0f7970d9391427641a720e6a97', "Assertion InResponseTo - ok");
110+
111+
is($assertion->{id}, 'ID_ef9c4328-63de-4d55-ae05-e5342e67f36c', "Assertion ID - ok");
112+
113+
########################################
114+
# LogoutResponse from ArtifactResponse #
115+
########################################
116+
my $logout_artifact = Net::SAML2::Protocol::Artifact->new_from_xml(
117+
xml => $artifact_logout_response,
118+
);
119+
120+
isa_ok($logout_artifact, "Net::SAML2::Protocol::Artifact");
121+
122+
my $logout = Net::SAML2::Protocol::LogoutResponse->new_from_xml(
123+
xml => $logout_artifact->logout_response,
124+
);
125+
126+
isa_ok($logout, "Net::SAML2::Protocol::LogoutResponse");
127+
128+
ok($logout->success(), "Logout Response has a Success");
129+
130+
is($logout->{response_to}, 'NETSAML2_0b499739aa1d76eb80093a068053b8fee62cade60f7dc27826d0f13b19cad16a', "Logout Response InResponseTo - ok");
131+
132+
is($logout->{id}, 'ID_bfc25851-4da2-4420-8240-9103b77b12dc', "Logout Response Id - ok");
133+
134+
$logout = Net::SAML2::Protocol::LogoutResponse->new_from_xml(
135+
xml => $logout_artifact->get_response(),
136+
);
137+
138+
isa_ok($logout, "Net::SAML2::Protocol::LogoutResponse", "from get_response");
139+
140+
ok($logout->success(), "Logout Response has a Success");
141+
142+
is($logout->{response_to}, 'NETSAML2_0b499739aa1d76eb80093a068053b8fee62cade60f7dc27826d0f13b19cad16a', "Logout Response InResponseTo - ok");
143+
144+
done_testing;

0 commit comments

Comments
 (0)