Skip to content

Commit b86345c

Browse files
committed
Merge pull request SAML-Toolkits#261 from sthanson/skip_validate_subject_confirmation_flag
Allow validate_subject_confirmation Response validation to be skipped
2 parents 7b4417e + ff99262 commit b86345c

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@ def saml_settings
166166
end
167167
```
168168
169+
Some assertion validations can be skipped by passing parameters to OneLogin::RubySaml::Response.new(). For example, you can skip the Conditions validation or the SubjectConfirmation validations by initializing the response with different options:
170+
171+
```ruby
172+
response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_conditions: true}) # skips conditions
173+
response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], {skip_subject_confirmation: true}) # skips subject confirmation
174+
```
175+
169176
What's left at this point, is to wrap it all up in a controller and point the initialization and consumption URLs in OneLogin at that. A full controller example could look like this:
170177
171178
```ruby

lib/onelogin/ruby-saml/response.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ class Response < SamlMessage
3636
# @param options [Hash] :settings to provide the OneLogin::RubySaml::Settings object
3737
# Or some options for the response validation process like skip the conditions validation
3838
# with the :skip_conditions, or allow a clock_drift when checking dates with :allowed_clock_drift
39-
# or :matches_request_id that will validate that the response matches the ID of the request.
39+
# or :matches_request_id that will validate that the response matches the ID of the request,
40+
# or skip the subject confirmation validation with the :skip_subject_confirmation option
4041
def initialize(response, options = {})
4142
@errors = []
4243

@@ -524,12 +525,14 @@ def validate_session_expiration(soft = true)
524525
end
525526

526527
# Validates if exists valid SubjectConfirmation (If the response was initialized with the :allowed_clock_drift option,
527-
# timimg validation are relaxed by the allowed_clock_drift value)
528+
# timimg validation are relaxed by the allowed_clock_drift value. If the response was initialized with the
529+
# :skip_subject_confirmation option, this validation is skipped)
528530
# If fails, the error is added to the errors array
529531
# @return [Boolean] True if exists a valid SubjectConfirmation, otherwise False if soft=True
530532
# @raise [ValidationError] if soft == false and validation fails
531533
#
532534
def validate_subject_confirmation
535+
return true if options[:skip_subject_confirmation]
533536
valid_subject_confirmation = false
534537

535538
subject_confirmation_nodes = xpath_from_signed_assertion('/a:Subject/a:SubjectConfirmation')

test/response_test.rb

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,27 @@ class RubySamlTest < Minitest::Test
616616
assert !response_invalid_subjectconfirmation_noa.send(:validate_subject_confirmation)
617617
assert_includes response_invalid_subjectconfirmation_noa.errors, "A valid SubjectConfirmation was not found on this Response"
618618
end
619+
620+
it "return true when the skip_subject_confirmation option is passed and the subject confirmation is valid" do
621+
opts = {}
622+
opts[:skip_subject_confirmation] = true
623+
response_with_skip = OneLogin::RubySaml::Response.new(response_document_valid_signed, opts)
624+
response_with_skip.settings = settings
625+
response_with_skip.settings.assertion_consumer_service_url = 'recipient'
626+
Time.expects(:now).times(0) # ensures the test isn't run and thus Time.now.utc is never called within the test
627+
assert response_with_skip.send(:validate_subject_confirmation)
628+
assert_empty response_with_skip.errors
629+
end
630+
631+
it "return true when the skip_subject_confirmation option is passed and the response has an invalid subject confirmation" do
632+
opts = {}
633+
opts[:skip_subject_confirmation] = true
634+
response_with_skip = OneLogin::RubySaml::Response.new(read_invalid_response("invalid_subjectconfirmation_noa.xml.base64"), opts)
635+
response_with_skip.settings = settings
636+
Time.expects(:now).times(0) # ensures the test isn't run and thus Time.now.utc is never called within the test
637+
assert response_with_skip.send(:validate_subject_confirmation)
638+
assert_empty response_with_skip.errors
639+
end
619640
end
620641

621642
describe "#validate_session_expiration" do
@@ -632,8 +653,8 @@ class RubySamlTest < Minitest::Test
632653
end
633654

634655
it "returns true when the session has expired, but is still within the allowed_clock_drift" do
635-
drift = (Time.now - Time.parse("2010-11-19T21:57:37Z")) * 60 # minutes ago that this assertion expired
636-
drift += 10 # add a buffer of 10 minutes to make sure the test passes
656+
drift = (Time.now - Time.parse("2010-11-19T21:57:37Z")) * 60 # seconds ago that this assertion expired
657+
drift += 10 # add a buffer of 10 seconds to make sure the test passes
637658
opts = {}
638659
opts[:allowed_clock_drift] = drift
639660

0 commit comments

Comments
 (0)