Net-SAML2
view release on metacpan or search on metacpan
t/16-encrypted-assertion.t view on Meta::CPAN
use strict;
use warnings;
use Test::Lib;
use Test::Net::SAML2;
use Net::SAML2::Protocol::Assertion;
use XML::Sig;
use MIME::Base64 qw/decode_base64/;
my $response = <<'RESPONSE';
PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIERlc3RpbmF0aW9uPSJodHRwczovL25ldHNhbWwyLXRlc3RhcHAubG9jYWwvY29uc3VtZXItcG9zdCIgSUQ9IklEXzZhNj...
RESPONSE
my $encryptedresponse = $response;
my $sp = net_saml2_sp();
$sp->{cacert} = 't/keycloak-cacert.pem';
my $post = $sp->post_binding;
my $subject;
lives_ok(
sub {
$subject = $post->handle_response($response);
},
'$sp->handle_response works'
);
# Trust-anchor enforcement on the encrypted-assertion path.
#
# Without a cacert configured on new_from_xml,
# _verify_encrypted_assertion previously short-circuited and accepted
# the KeyInfo-embedded signing certificate. new_from_xml now refuses
# unless the caller explicitly opts out via insecure_trust_embedded_cert.
throws_ok(sub {
Net::SAML2::Protocol::Assertion->new_from_xml(
xml => decode_base64($response),
key_file => 't/encrypted-sign-private.pem',
# no cacert
);
}, qr/'cacert' or 'cert_text' is required to verify/, 'encrypted assertion without cacert croaks');
lives_ok(sub {
Net::SAML2::Protocol::Assertion->new_from_xml(
xml => decode_base64($response),
key_file => 't/encrypted-sign-private.pem',
insecure_trust_embedded_cert => 1,
);
}, 'explicit insecure_trust_embedded_cert opt-out lets encrypted assertion through');
# require_signed_assertion: when set, the decrypted assertion must
# carry a <dsig:Signature>. The existing fixture is a signed encrypted
# assertion, so this is the positive case (does not regress).
lives_ok(sub {
Net::SAML2::Protocol::Assertion->new_from_xml(
xml => decode_base64($response),
key_file => 't/encrypted-sign-private.pem',
cacert => 't/keycloak-cacert.pem',
require_signed_assertion => 1,
);
}, 'require_signed_assertion accepts a properly signed encrypted assertion');
# Negative case (unsigned encrypted assertion + require_signed_assertion
# => 1 should croak) would need an unsigned-encrypted-assertion fixture
# that is not present in this test data. To be added when such a
# fixture lands; the code path is the one above with the new croak.
my $assertion = Net::SAML2::Protocol::Assertion->new_from_xml(
xml => decode_base64($response),
key_file => 't/encrypted-sign-private.pem',
cacert => 't/keycloak-cacert.pem',
);
isa_ok($assertion, 'Net::SAML2::Protocol::Assertion');
is($assertion->in_response_to, 'NETSAML2_935c782d5f5e499638a7471b257062b5');
is(scalar keys %{ $assertion->attributes }, 4);
is(scalar @{ $assertion->attributes->{EmailAddress} }, 1);
is($assertion->session, '91af7e38-e3a6-4be4-9d91-04a32c2ddee2::29499342-7453-4345-b702-68351fcad4f2', 'Session ID is correct');
is($assertion->nameid, 'timlegge@cpan.org', 'Name ID is correct');
cmp_deeply(
$assertion->attributes,
{
EmailAddress => [qw(timlegge@cpan.org)],
CN => [qw(keycloak.local)],
FirstName => [qw(Timothy)],
Role => [qw(manage-account)],
},
"Assertion attributes are ok"
);
isa_ok($assertion->not_before, 'DateTime');
isa_ok($assertion->not_after, 'DateTime');
is($assertion->audience, 'https://netsaml2-testapp.local', "Assertion audience is ct.local");
is($assertion->valid('foo'), 0, "foo isn't a valid assertion");
is($assertion->valid('ct.local'), 0, "ct.local isn't valid either");
# fudge validity times to test valid()
$assertion->{not_before} = DateTime->now;
$assertion->{not_after} = DateTime->now->add(minutes => 15);
is($assertion->valid('https://netsaml2-testapp.local'), 1, "https://netsaml2-testapp.local is valid now - InResponseTo not Checked");
is($assertion->valid('https://netsaml2-testapp.local', 'NETSAML2_935c782d5f5e499638a7471b257062b5'), 1, "https://netsaml2-testapp.local is valid now - InResponseTo Checked");
is($assertion->valid('https://netsaml2-testapp.local', 'NETSAML2_935c782d5f5e499638a7471b257062'), 0, "Invalid InResponseTo Checked and failed");
$assertion->{not_before} = DateTime->now->add(minutes => 5);
is($assertion->valid('http://ct.local'), 0, "and invalid again - InResponseTo not Checked");
is($assertion->valid('http://ct.local', 'N3k95Hg41WCHdwc9mqXynLPhB'), 0, "and invalid again - InResponseTo Checked");
( run in 0.941 second using v1.01-cache-2.11-cpan-5fbc6bb55f2 )