Net-SAML2

 view release on metacpan or  search on metacpan

lib/Net/SAML2/SP.pm  view on Meta::CPAN

    $use = 'signing' if $self->signing_only && $use eq 'both';

    return $x->KeyDescriptor(
        $md,
        $use ne 'both' ? { use => $use } : {},
        $x->KeyInfo(
            $ds,
            $x->X509Data($ds, $x->X509Certificate($ds, $key)),
            $x->KeyName($ds, $self->key_name($use)),
        ),
    );
}


sub key_name {
    my $self = shift;
    my $use  = shift;
    my $key = $use eq 'encryption' ? $self->_encryption_key_text : $self->_cert_text;
    return unless $key;
    return Digest::MD5::md5_hex($key);
}

sub _generate_single_logout_service {
    my $self = shift;
    my $x    = shift;
    return map { $x->SingleLogoutService($md, $_) } @{ $self->single_logout_service };
}

sub _generate_assertion_consumer_service {
    my $self = shift;
    my $x    = shift;
    return map { $x->AssertionConsumerService($md, $_) } @{ $self->assertion_consumer_service };
}



sub metadata {
    my $self = shift;

    my $metadata = $self->generate_metadata();
    return $metadata->stringify unless $self->sign_metadata;

    use Net::SAML2::XML::Sig;
    my $signer = Net::SAML2::XML::Sig->new(
        {
            key         => $self->key,
            cert        => $self->cert,
            sig_hash    => 'sha256',
            digest_hash => 'sha256',
            x509        => 1,
            ns          => { md => URN_METADATA },
            id_attr     => '/md:EntityDescriptor[@ID]',
        }
    );
    my $md = $signer->sign($metadata);

    my $xp = XML::LibXML::XPathContext->new(
        XML::LibXML->load_xml(string =>$md)
    );
    $xp->registerNs('md', URN_METADATA);
    $xp->registerNs('dsig', URN_SIGNATURE);

    my $nodes = $xp->findnodes('/md:EntityDescriptor[@ID]');
    my $rootnode = $nodes->get_node(1);

    my $child = $rootnode->firstChild;
    return $md if $child->nodeName() eq 'dsig:Signature';

    $nodes = $xp->findnodes('//dsig:Signature');
    my $signode = $nodes->get_node(1);

    $signode->unbindNode;
    $rootnode->insertBefore($signode, $child);

    return '<?xml version="1.0" encoding="UTF-8"?>' . $rootnode->toString;
}


sub get_default_assertion_service {
    my $self = shift;
    my $default = first { $_->{isDefault} eq 1 || $_->{isDefault} eq 'true' }
        grep { defined $_->{isDefault} } @{ $self->assertion_consumer_service };
    return $default if $default;

    $default = first { ! defined $_->{isDefault} } @{ $self->assertion_consumer_service };
    return $default if $default;

    return $self->assertion_consumer_service->[0];
}

__PACKAGE__->meta->make_immutable;

__END__

=pod

=encoding UTF-8

=head1 NAME

Net::SAML2::SP - SAML Service Provider object

=head1 VERSION

version 0.85

=head1 SYNOPSIS

my $sp = Net::SAML2::SP->new(
    issuer => 'http://localhost:3000',
    url    => 'http://localhost:3000',
    cert   => 'sign-nopw-cert.pem',
    key    => 'sign-nopw-key.pem',
);

=head1 METHODS

=head2 new( ... )

Constructor. Create an SP object.

Arguments:

=over

=item B<id>

The ID attribute used in the EntityDescription tag



( run in 1.137 second using v1.01-cache-2.11-cpan-5a3173703d6 )