-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is to accomodate responses which do not include Assertions Signed-off-by: Wesley Schwengle <waterkip@cpan.org>
- Loading branch information
Showing
4 changed files
with
237 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package Net::SAML2::Object::Response; | ||
use Moose; | ||
|
||
|
||
use overload '""' => 'to_string'; | ||
|
||
# ABSTRACT: A response object | ||
|
||
use MooseX::Types::DateTime qw/ DateTime /; | ||
use MooseX::Types::Common::String qw/ NonEmptySimpleStr /; | ||
use DateTime; | ||
use DateTime::HiRes; | ||
use DateTime::Format::XSD; | ||
use Net::SAML2::XML::Util qw/ no_comments /; | ||
use Net::SAML2::XML::Sig; | ||
use XML::Enc; | ||
use XML::LibXML::XPathContext; | ||
use List::Util qw(first); | ||
use URN::OASIS::SAML2 qw(STATUS_SUCCESS URN_ASSERTION URN_PROTOCOL); | ||
use Carp qw(croak); | ||
|
||
with 'Net::SAML2::Role::ProtocolMessage'; | ||
|
||
# ABSTRACT: SAML2 response object | ||
|
||
has _dom => ( | ||
is => 'ro', | ||
isa => 'XML::LibXML::Node', | ||
init_arg => 'dom', | ||
required => 1, | ||
); | ||
|
||
has status => ( | ||
is => 'ro', | ||
isa => 'Str', | ||
required => 1, | ||
); | ||
|
||
has sub_status => ( | ||
is => 'ro', | ||
isa => 'Str', | ||
required => 0, | ||
predicate => 'has_sub_status', | ||
); | ||
|
||
has assertions => ( | ||
is => 'ro', | ||
isa => 'XML::LibXML::NodeList', | ||
required => 0, | ||
predicate => 'has_assertions', | ||
); | ||
|
||
sub new_from_xml { | ||
my $self = shift; | ||
my %args = @_; | ||
|
||
my $xml = no_comments($args{xml}); | ||
|
||
my $xpath = XML::LibXML::XPathContext->new($xml); | ||
$xpath->registerNs('saml', URN_ASSERTION); | ||
$xpath->registerNs('samlp', URN_PROTOCOL); | ||
|
||
my $response = $xpath->findnodes('/samlp:Response|/samlp:ArtifactResponse'); | ||
croak("Unable to parse response") unless $response->size; | ||
$response = $response->get_node(1); | ||
|
||
my $code_path = 'samlp:Status/samlp:StatusCode'; | ||
if ($response->nodePath eq '/samlp:ArtifactResponse') { | ||
$code_path = "samlp:Response/$code_path"; | ||
} | ||
|
||
my $status = $xpath->findnodes($code_path, $response); | ||
croak("Unable to parse status from response") unless $status->size; | ||
|
||
my $status_node = $status->get_node(1); | ||
$status = $status_node->getAttribute('Value'); | ||
|
||
my $substatus = $xpath->findvalue('samlp:StatusCode/@Value', $status_node); | ||
|
||
my $nodes = $xpath->findnodes('//saml:EncryptedAssertion|//saml:Assertion', $response); | ||
|
||
return $self->new( | ||
dom => $xml, | ||
status => $status, | ||
$substatus ? ( sub_status => $substatus) : (), | ||
issuer => $xpath->findvalue('saml:Issuer', $response), | ||
id => $response->getAttribute('ID'), | ||
in_response_to => $response->getAttribute('InResponseTo'), | ||
$nodes->size ? (assertions => $nodes) : (), | ||
); | ||
} | ||
|
||
sub to_string { | ||
my $self = shift; | ||
return $self->_dom->toString; | ||
} | ||
|
||
sub to_assertion { | ||
my $self = shift; | ||
my @args = @_; | ||
|
||
if (!$self->has_assertions) { | ||
croak("There are no assertions found in the response object"); | ||
} | ||
|
||
return Net::SAML2::Protocol::Assertion->new_from_xml( | ||
@args, | ||
xml => $self->to_string, | ||
); | ||
} | ||
|
||
1; | ||
|
||
|
||
__PACKAGE__->meta->make_immutable; | ||
|
||
__END__ | ||
=head1 DESCRIPTION | ||
=head1 SYNOPSIS | ||
use Net::SAML2::Object::Response; | ||
my $var = Net::SAML2::Object::Response->new(...); | ||
$var->method(...); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
use strict; | ||
use warnings; | ||
use Test::Lib; | ||
use Test::Net::SAML2; | ||
|
||
use Net::SAML2::Object::Response; | ||
use URN::OASIS::SAML2 qw(STATUS_RESPONDER STATUS_AUTH_FAILED); | ||
|
||
sub get_object { | ||
my $xml = path(shift)->slurp; | ||
my $response = Net::SAML2::Object::Response->new_from_xml(xml => $xml); | ||
isa_ok($response, 'Net::SAML2::Object::Response'); | ||
return $response; | ||
} | ||
|
||
{ | ||
my $response = get_object('t/data/digid-anul-artifact-response.xml'); | ||
ok(!$response->has_assertions, "We don't have an assertion"); | ||
ok(!$response->success, "Unsuccessful response"); | ||
is($response->status, STATUS_RESPONDER(), "... because its a status:Responder"); | ||
is($response->sub_status, STATUS_AUTH_FAILED(), "... and substatus is also correct"); | ||
} | ||
|
||
|
||
{ | ||
my $response = get_object('t/data/eherkenning-assertion.xml'); | ||
ok($response->has_assertions, "We have an assertion"); | ||
ok($response->success, "It was successful"); | ||
is($response->assertions->size, 3, "Got the correct amount or assertions"); | ||
|
||
my $assertion = $response->to_assertion(); | ||
isa_ok($assertion, "Net::SAML2::Protocol::Assertion"); | ||
} | ||
|
||
|
||
{ | ||
my $response = get_object('t/data/response-no-assertion.xml'); | ||
ok(!$response->has_assertions, "We don't have an assertion"); | ||
ok(!$response->success, "Unsuccessful response"); | ||
is($response->status, STATUS_RESPONDER(), "... because its a status:Responder"); | ||
} | ||
done_testing; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?xml version="1.0"?> | ||
<samlp:ArtifactResponse xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" ID="_5ede0a3002fb0efe627efc4bf3a076b7a3810a80" Version="2.0" IssueInstant="2024-04-16T14:52:40Z" InResponseTo="NETSAML2_10aad5b7776e047b40637fec9793fa1b8259e7e7845ca379cd8a01008e1b93f8"> | ||
<saml:Issuer>https://was-preprod1.digid.nl/saml/idp/metadata</saml:Issuer> | ||
<ds:Signature> | ||
<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="#_5ede0a3002fb0efe627efc4bf3a076b7a3810a80"> | ||
<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#"> | ||
<ec:InclusiveNamespaces PrefixList="ds saml samlp xs"/> | ||
</ds:Transform> | ||
</ds:Transforms> | ||
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||
<ds:DigestValue>value here</ds:DigestValue> | ||
</ds:Reference> | ||
</ds:SignedInfo> | ||
<ds:SignatureValue>some sig here</ds:SignatureValue> | ||
<ds:KeyInfo> | ||
<ds:KeyName>7593b799e735055fcd479caa35d44d455576cefc</ds:KeyName> | ||
<ds:X509Data> | ||
<ds:X509Certificate>Some cert here</ds:X509Certificate> | ||
</ds:X509Data> | ||
</ds:KeyInfo> | ||
</ds:Signature> | ||
<samlp:Status> | ||
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> | ||
</samlp:Status> | ||
<samlp:Response ID="_bee5133d91cddac59c1943a451915948a0563d5b" Version="2.0" IssueInstant="2024-04-16T14:52:40Z" InResponseTo="NETSAML2_730fbcbf9aca0d79eb18aeee3ad03908f805a3b441d586753c6dd68e53cb5d73"> | ||
<saml:Issuer>https://was-preprod1.digid.nl/saml/idp/metadata</saml:Issuer> | ||
<samlp:Status> | ||
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder"> | ||
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:AuthnFailed"/> | ||
</samlp:StatusCode> | ||
</samlp:Status> | ||
</samlp:Response> | ||
</samlp:ArtifactResponse> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<samlp:Response ID="_ae896f90-5ecb-4d00-8738-91337236a165" Version="2.0" | ||
IssueInstant="2024-04-10T13:17:32.119Z" Destination="[our SAML callback url]" | ||
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" | ||
InResponseTo="NETSAML2_d54e304a5472d4429f20e3d44a7a224b" | ||
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> | ||
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://[IdP testing | ||
domain]/adfs/services/trust</Issuer> | ||
<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="#_ae896f90-5ecb-4d00-8738-91337236a165"> | ||
<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>K4r9/0ZZqW32TG+jT9tGsKwYKwNzssSSKIo8gvWPCfo=</ds:DigestValue> | ||
</ds:Reference> | ||
</ds:SignedInfo> | ||
<ds:SignatureValue>[the signature value]</ds:SignatureValue> | ||
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> | ||
<ds:X509Data> | ||
<ds:X509Certificate>[the certificate]</ds:X509Certificate> | ||
</ds:X509Data> | ||
</KeyInfo> | ||
</ds:Signature> | ||
<samlp:Status> | ||
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder" /> | ||
</samlp:Status> | ||
</samlp:Response> |