Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[improvements] Return error to application and support SLO request validation #224

Merged
merged 21 commits into from
Oct 29, 2024

Conversation

Zogoo
Copy link
Collaborator

@Zogoo Zogoo commented Oct 24, 2024

This PR contains the following improvements.
The reason for combining these changes into a single pull request (PR) is that they do not directly affect the gem's core features. Splitting my code into smaller PRs would require manual tasks, which can introduce bugs. Additionally, all these improvements have already been tested in a real environment.

  1. Currently, the gem is failing silently and only provides logs which makes the application cannot take any actions based on failure. For example, it should display errors related to the customer's configurations. To address this, I added an error collection to the SAML request. After validation, these errors will be stored in an array for further processing.
  2. Allow the application to retrieve metadata for usage that is not defined as unspecified_certificate.
  3. Follow the metadata instructions on how to validate the Authn Request. If the metadata specifies that it should be signed, the IdP should accept a signed Authn Request.

zogoo and others added 13 commits July 25, 2024 00:50
* Allow SP config force signature validation

* Allow SP config force signature validation

Tested with Slack with Authn request signature option
---------

Co-authored-by: zogoo <[email protected]>
I have tested with live SAML SP apps and it works fine

* Unspecified certifciate from SP metadata

---------

Co-authored-by: zogoo <[email protected]>
* Set minimum test coverage (saml-idp#207)

* Set minimum test coverage to a very high value for testing

* Update minimum coverage to actual current value

* Try with proper way to update helper method

* Correctly decode and mock with correct REXML class

* Drop the min coverage

---------

Co-authored-by: Mathieu Jobin <[email protected]>
Co-authored-by: zogoo <[email protected]>
* wip add error collector

* Fix type and rewrite request with proper validation test cases

* Lead error render decision to gem user

* Validate the certificate's existence before verifying the signature.

---------

Co-authored-by: zogoo <[email protected]>
@Zogoo Zogoo requested a review from jphenow October 24, 2024 21:46
@Zogoo Zogoo self-assigned this Oct 24, 2024
@@ -34,10 +34,7 @@ def acs_url

def validate_saml_request(raw_saml_request = params[:SAMLRequest])
decode_request(raw_saml_request, params[:Signature], params[:SigAlg], params[:RelayState])
return true if valid_saml_request?

head :forbidden if defined?(::Rails)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was not UX friendly option that rendered a black screen from the gem. We should leave this decision to the application side and only provide helper methods.

@Zogoo
Copy link
Collaborator Author

Zogoo commented Oct 27, 2024

@jphenow can you look at this one?

@@ -63,6 +63,15 @@ def contact_person
end
hashable :contact_person

def unspecified_certificate
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One example of SAML 2.0 spec it has too many optional fields for a too generic solution.
Gem missing if there certificate without specifying usage (@use='signing') of the certificate. For this reason, we need to at least make it retrievable for application.

@@ -3,6 +3,8 @@
require 'logger'
module SamlIdp
class Request
attr_accessor :errors
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Collecting errors for application then application can decide action based on error.

# Match all percent-encoded sequences (e.g., %20, %2B) and convert them to lowercase
# Upper case is recommended for consistency but some services such as MS Entra Id not follows it
# https://datatracker.ietf.org/doc/html/rfc3986#section-2.1
result || cert.public_key.verify(signature_algorithm.new, raw_signature, query_request_string.gsub(/%[A-F0-9]{2}/) { |match| match.downcase })
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lowercase URL encoding is also possible, but the signature is case-sensitive.
For this case, we need to try both cases for signature verification.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proper SLO test with ruby-saml gem.

@@ -51,7 +51,7 @@ def signature_fingerprint_1
@signature_fingerprint1 ||= "C5:19:85:D9:47:F1:BE:57:08:20:25:05:08:46:EB:27:F6:CA:B7:83"
end

def signature_1
def certificate_1
Copy link
Collaborator Author

@Zogoo Zogoo Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a certificate, not a signature.

@Zogoo Zogoo merged commit 4b7e4c8 into saml-idp:master Oct 29, 2024
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants