diff --git a/lib/onelogin/ruby-saml/response.rb b/lib/onelogin/ruby-saml/response.rb index 29d48594..31000f69 100644 --- a/lib/onelogin/ruby-saml/response.rb +++ b/lib/onelogin/ruby-saml/response.rb @@ -198,6 +198,27 @@ def session_expires_at end end + # Gets the AuthnInstant from the AuthnStatement. + # Could be used to require re-authentication if a long time has passed + # since the last user authentication. + # @return [String] AuthnInstant value + # + def authn_instant + @authn_instant ||= begin + node = xpath_first_from_signed_assertion('/a:AuthnStatement') + node.nil? ? nil : node.attributes['AuthnInstant'] + end + end + + # Gets the AuthnContextClassRef from the AuthnStatement + # Could be used to require re-authentication if the assertion + # did not met the requested authentication context class. + # @return [String] AuthnContextClassRef value + # + def authn_context_class_ref + @authn_context_class_ref ||= Utils.element_text(xpath_first_from_signed_assertion('/a:AuthnStatement/a:AuthnContext/a:AuthnContextClassRef')) + end + # Checks if the Status has the "Success" code # @return [Boolean] True if the StatusCode is Sucess # diff --git a/test/response_test.rb b/test/response_test.rb index f2fca3eb..ee8fb1b0 100644 --- a/test/response_test.rb +++ b/test/response_test.rb @@ -1357,6 +1357,18 @@ def generate_audience_error(expected, actual) end end + describe "#authn_instant" do + it "extract the value of the AuthnInstant attribute" do + assert_equal "2010-11-18T21:57:37Z", response.authn_instant + end + end + + describe "#authn_context_class_ref" do + it "extract the value of the AuthnContextClassRef attribute" do + assert_equal "urn:oasis:names:tc:SAML:2.0:ac:classes:Password", response.authn_context_class_ref + end + end + describe "#success" do it "find a status code that says success" do response.success?