Commit 8942f86
Changed files (4)
lib
saml
spec
lib/saml/kit/assertion.rb
@@ -32,7 +32,9 @@ module Saml
end
def active?
- Time.current > started_at && !expired?
+ clock_drift = configuration.clock_drift
+ start = clock_drift.before(started_at)
+ Time.current > start && !expired?
end
def attributes
@@ -69,9 +71,11 @@ module Saml
private
+ attr_reader :configuration
+
def assertion
@assertion ||= if encrypted?
- decrypted = XmlDecryption.new(configuration: @configuration).decrypt(@xml_hash['Response']['EncryptedAssertion'])
+ decrypted = XmlDecryption.new(configuration: configuration).decrypt(@xml_hash['Response']['EncryptedAssertion'])
Saml::Kit.logger.debug(decrypted)
Hash.from_xml(decrypted)['Assertion']
else
@@ -91,7 +95,7 @@ module Saml
end
def must_match_issuer
- unless audiences.include?(@configuration.issuer)
+ unless audiences.include?(configuration.issuer)
errors[:audience] << error_message(:must_match_issuer)
end
end
lib/saml/kit/configuration.rb
@@ -32,14 +32,17 @@ module Saml
attr_accessor :session_timeout
# The logger to write log messages to.
attr_accessor :logger
+ # The total allowable clock drift for session timeout validation.
+ attr_accessor :clock_drift
def initialize # :yields configuration
- @signature_method = :SHA256
+ @clock_drift = 30.seconds
@digest_method = :SHA256
+ @key_pairs = []
+ @logger = Logger.new(STDOUT)
@registry = DefaultRegistry.new
@session_timeout = 3.hours
- @logger = Logger.new(STDOUT)
- @key_pairs = []
+ @signature_method = :SHA256
yield self if block_given?
end
spec/saml/assertion_spec.rb
@@ -0,0 +1,29 @@
+RSpec.describe Saml::Kit::Assertion do
+ describe "#active?" do
+ let(:configuration) do
+ Saml::Kit::Configuration.new do |config|
+ config.session_timeout = 30.minutes
+ config.clock_drift = 30.seconds
+ end
+ end
+
+ it 'is valid after a valid session window + drift' do
+ now = Time.current
+ travel_to now
+ xml_hash = {
+ 'Response' => {
+ 'Assertion' => {
+ 'Conditions' => {
+ 'NotBefore' => now.utc.iso8601,
+ 'NotOnOrAfter' => configuration.session_timeout.since(now).iso8601,
+ }
+ }
+ }
+ }
+ subject = described_class.new(xml_hash, configuration: configuration)
+ travel_to (configuration.clock_drift - 1.second).before(now)
+ expect(subject).to be_active
+ expect(subject).to_not be_expired
+ end
+ end
+end
spec/saml/response_spec.rb
@@ -125,7 +125,7 @@ RSpec.describe Saml::Kit::Response do
allow(metadata).to receive(:matches?).and_return(true)
subject = described_class.build(user, request)
- travel_to 5.seconds.ago
+ travel_to (Saml::Kit.configuration.clock_drift + 1.second).before(Time.now)
expect(subject).to be_invalid
expect(subject.errors[:base]).to be_present
end