@@ -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
@@ -178,6 +185,11 @@ sub new_from_xml {
178185 $nameid = $global -> get_node(1);
179186 }
180187
188+ my $authnstatement ;
189+ if (my $node = $xpath -> findnodes(' /samlp:Response/saml:Assertion/saml:AuthnStatement' )) {
190+ $authnstatement = $node -> get_node(1);
191+ }
192+
181193 my $nodeset = $xpath -> findnodes(' /samlp:Response/samlp:Status/samlp:StatusCode|/samlp:ArtifactResponse/samlp:Status/samlp:StatusCode' );
182194
183195 croak(" Unable to parse status from assertion" ) unless $nodeset -> size;
@@ -204,6 +216,7 @@ sub new_from_xml {
204216 in_response_to => $xpath -> findvalue(' //saml:Subject/saml:SubjectConfirmation/saml:SubjectConfirmationData/@InResponseTo' ),
205217 response_status => $status ,
206218 $sub_status ? (response_substatus => $sub_status ) : (),
219+ $authnstatement ? (authnstatement => $authnstatement ) : (),
207220 );
208221
209222 return $self ;
@@ -290,6 +303,131 @@ sub nameid_sp_provided_id {
290303 return $self -> nameid_object-> getAttribute(' SPProvidedID' );
291304}
292305
306+ =head2 authnstatement
307+
308+ Returns the AuthnStatement
309+
310+ =cut
311+
312+ sub authnstatement {
313+ my $self = shift ;
314+ return unless $self -> has_authnstatement;
315+ return $self -> authnstatement_object-> textContent;
316+ }
317+
318+ =head2 authnstatement_authninstant
319+
320+ Returns the AuthnStatement AuthnInstant
321+
322+ =cut
323+
324+ sub authnstatement_authninstant {
325+ my $self = shift ;
326+ return unless $self -> has_authnstatement;
327+ return $self -> authnstatement_object-> getAttribute(' AuthnInstant' );
328+ }
329+
330+ =head2 authnstatement_sessionindex
331+
332+ Returns the AuthnStatement SessionIndex
333+
334+ =cut
335+
336+ sub authnstatement_sessionindex {
337+ my $self = shift ;
338+ return unless $self -> has_authnstatement;
339+ return $self -> authnstatement_object-> getAttribute(' SessionIndex' );
340+ }
341+
342+ =head2 authnstatement_subjectlocality
343+
344+ Returns the AuthnStatement SubjectLocality
345+
346+ =cut
347+
348+ sub authnstatement_subjectlocality {
349+ my $self = shift ;
350+ return unless $self -> has_authnstatement;
351+
352+ my $xpc = XML::LibXML::XPathContext-> new;
353+ $xpc -> registerNs(' saml' , ' urn:oasis:names:tc:SAML:2.0:assertion' );
354+ my $subjectlocality ;
355+ my $xpath_base = ' //saml:AuthnStatement/saml:SubjectLocality' ;
356+ if (my $nodes = $xpc -> find($xpath_base , $self -> authnstatement_object)) {
357+ my $node = $nodes -> get_node(1);
358+ $subjectlocality = $node ;
359+ }
360+ return $subjectlocality ;
361+ }
362+
363+ =head2 subjectlocality_address
364+
365+ Returns the SubjectLocality Address
366+
367+ =cut
368+
369+ sub subjectlocality_address {
370+ my $self = shift ;
371+ return unless $self -> has_authnstatement;
372+ my $subjectlocality = $self -> authnstatement_subjectlocality;
373+ return unless $subjectlocality ;
374+ return $subjectlocality -> getAttribute(' Address' );
375+ }
376+
377+ =head2 subjectlocality_dnsname
378+
379+ Returns the SubjectLocality DNSName
380+
381+ =cut
382+
383+ sub subjectlocality_dnsname {
384+ my $self = shift ;
385+ return unless $self -> has_authnstatement;
386+ my $subjectlocality = $self -> authnstatement_subjectlocality;
387+ return unless $subjectlocality ;
388+ return $subjectlocality -> getAttribute(' DNSName' );
389+ }
390+
391+ =head2 authnstatement_authncontext
392+
393+ Returns the AuthnContext for the AuthnStatement
394+
395+ =cut
396+
397+ sub authnstatement_authncontext {
398+ my $self = shift ;
399+ return unless $self -> has_authnstatement;
400+
401+ my $xpc = XML::LibXML::XPathContext-> new;
402+ $xpc -> registerNs(' saml' , ' urn:oasis:names:tc:SAML:2.0:assertion' );
403+ my $authncontext ;
404+ my $xpath_base = ' //saml:AuthnStatement/saml:AuthnContext' ;
405+ if (my $nodes = $xpc -> find($xpath_base , $self -> authnstatement_object)) {
406+ my $node = $nodes -> get_node(1);
407+ $authncontext = $node ;
408+ }
409+ return $authncontext ;
410+ }
411+
412+ =head2 contextclass_authncontextclassref
413+
414+ Returns the ContextClass AuthnContextClassRef
415+
416+ =cut
417+
418+ sub contextclass_authncontextclassref {
419+ my $self = shift ;
420+ return unless $self -> has_authnstatement;
421+ my $authncontextclassref = $self -> authnstatement_authncontext;
422+ return unless $authncontextclassref ;
423+ my $xpc = XML::LibXML::XPathContext-> new;
424+ $xpc -> registerNs(' saml' , ' urn:oasis:names:tc:SAML:2.0:assertion' );
425+ if (my $value = $xpc -> findvalue(' //saml:AuthnContextClassRef' , $self -> authnstatement_object)) {
426+ $authncontextclassref = $value ;
427+ }
428+ return $authncontextclassref ;
429+ }
430+
293431=head2 valid( $audience, $in_response_to )
294432
295433Returns true if this Assertion is currently valid for the given audience.
0 commit comments