@@ -48,6 +48,13 @@ has 'nameid_object' => (
4848 init_arg => ' nameid' ,
4949 predicate => ' has_nameid' ,
5050);
51+ has ' authnstatement_object' => (
52+ isa => ' XML::LibXML::Element' ,
53+ is => ' ro' ,
54+ required => 0,
55+ init_arg => ' authnstatement' ,
56+ predicate => ' has_authnstatement' ,
57+ );
5158
5259=head1 METHODS
5360
@@ -172,6 +179,11 @@ sub new_from_xml {
172179 $nameid = $global -> get_node(1);
173180 }
174181
182+ my $authnstatement ;
183+ if (my $node = $xpath -> findnodes(' /samlp:Response/saml:Assertion/saml:AuthnStatement' )) {
184+ $authnstatement = $node -> get_node(1);
185+ }
186+
175187 my $nodeset = $xpath -> findnodes(' /samlp:Response/samlp:Status/samlp:StatusCode|/samlp:ArtifactResponse/samlp:Status/samlp:StatusCode' );
176188
177189 croak(" Unable to parse status from assertion" ) unless $nodeset -> size;
@@ -198,6 +210,7 @@ sub new_from_xml {
198210 in_response_to => $xpath -> findvalue(' //saml:Subject/saml:SubjectConfirmation/saml:SubjectConfirmationData/@InResponseTo' ),
199211 response_status => $status ,
200212 $sub_status ? (response_substatus => $sub_status ) : (),
213+ $authnstatement ? (authnstatement => $authnstatement ) : (),
201214 );
202215
203216 return $self ;
@@ -285,6 +298,131 @@ sub nameid_sp_provided_id {
285298 return $self -> nameid_object-> getAttribute(' SPProvidedID' );
286299}
287300
301+ =head2 authnstatement
302+
303+ Returns the AuthnStatement
304+
305+ =cut
306+
307+ sub authnstatement {
308+ my $self = shift ;
309+ return unless $self -> has_authnstatement;
310+ return $self -> authnstatement_object-> textContent;
311+ }
312+
313+ =head2 authnstatement_authninstant
314+
315+ Returns the AuthnStatement AuthnInstant
316+
317+ =cut
318+
319+ sub authnstatement_authninstant {
320+ my $self = shift ;
321+ return unless $self -> has_authnstatement;
322+ return $self -> authnstatement_object-> getAttribute(' AuthnInstant' );
323+ }
324+
325+ =head2 authnstatement_sessionindex
326+
327+ Returns the AuthnStatement SessionIndex
328+
329+ =cut
330+
331+ sub authnstatement_sessionindex {
332+ my $self = shift ;
333+ return unless $self -> has_authnstatement;
334+ return $self -> authnstatement_object-> getAttribute(' SessionIndex' );
335+ }
336+
337+ =head2 authnstatement_subjectlocality
338+
339+ Returns the AuthnStatement SubjectLocality
340+
341+ =cut
342+
343+ sub authnstatement_subjectlocality {
344+ my $self = shift ;
345+ return unless $self -> has_authnstatement;
346+
347+ my $xpc = XML::LibXML::XPathContext-> new;
348+ $xpc -> registerNs(' saml' , ' urn:oasis:names:tc:SAML:2.0:assertion' );
349+ my $subjectlocality ;
350+ my $xpath_base = ' //saml:AuthnStatement/saml:SubjectLocality' ;
351+ if (my $nodes = $xpc -> find($xpath_base , $self -> authnstatement_object)) {
352+ my $node = $nodes -> get_node(1);
353+ $subjectlocality = $node ;
354+ }
355+ return $subjectlocality ;
356+ }
357+
358+ =head2 subjectlocality_address
359+
360+ Returns the SubjectLocality Address
361+
362+ =cut
363+
364+ sub subjectlocality_address {
365+ my $self = shift ;
366+ return unless $self -> has_authnstatement;
367+ my $subjectlocality = $self -> authnstatement_subjectlocality;
368+ return unless $subjectlocality ;
369+ return $subjectlocality -> getAttribute(' Address' );
370+ }
371+
372+ =head2 subjectlocality_dnsname
373+
374+ Returns the SubjectLocality DNSName
375+
376+ =cut
377+
378+ sub subjectlocality_dnsname {
379+ my $self = shift ;
380+ return unless $self -> has_authnstatement;
381+ my $subjectlocality = $self -> authnstatement_subjectlocality;
382+ return unless $subjectlocality ;
383+ return $subjectlocality -> getAttribute(' DNSName' );
384+ }
385+
386+ =head2 authnstatement_authncontext
387+
388+ Returns the AuthnContext for the AuthnStatement
389+
390+ =cut
391+
392+ sub authnstatement_authncontext {
393+ my $self = shift ;
394+ return unless $self -> has_authnstatement;
395+
396+ my $xpc = XML::LibXML::XPathContext-> new;
397+ $xpc -> registerNs(' saml' , ' urn:oasis:names:tc:SAML:2.0:assertion' );
398+ my $authncontext ;
399+ my $xpath_base = ' //saml:AuthnStatement/saml:AuthnContext' ;
400+ if (my $nodes = $xpc -> find($xpath_base , $self -> authnstatement_object)) {
401+ my $node = $nodes -> get_node(1);
402+ $authncontext = $node ;
403+ }
404+ return $authncontext ;
405+ }
406+
407+ =head2 contextclass_authncontextclassref
408+
409+ Returns the ContextClass AuthnContextClassRef
410+
411+ =cut
412+
413+ sub contextclass_authncontextclassref {
414+ my $self = shift ;
415+ return unless $self -> has_authnstatement;
416+ my $authncontextclassref = $self -> authnstatement_authncontext;
417+ return unless $authncontextclassref ;
418+ my $xpc = XML::LibXML::XPathContext-> new;
419+ $xpc -> registerNs(' saml' , ' urn:oasis:names:tc:SAML:2.0:assertion' );
420+ if (my $value = $xpc -> findvalue(' //saml:AuthnContextClassRef' , $self -> authnstatement_object)) {
421+ $authncontextclassref = $value ;
422+ }
423+ return $authncontextclassref ;
424+ }
425+
288426=head2 valid( $audience, $in_response_to )
289427
290428Returns true if this Assertion is currently valid for the given audience.
0 commit comments