Skip to content

Instantly share code, notes, and snippets.

@jonathan
Created December 13, 2013 21:25
Show Gist options
  • Save jonathan/7951578 to your computer and use it in GitHub Desktop.
Save jonathan/7951578 to your computer and use it in GitHub Desktop.
Saml message test validation
name_id = "1234567"
time = Time.now
Saml.current_provider = Saml.provider("com:localhost")
status_code = Saml::Elements::StatusCode.new(value: Saml::TopLevelCodes::SUCCESS)
status = Saml::Elements::Status.new(status_code: status_code)
partner_id = Saml::Elements::Attribute.new(
name: "PartnerId",
format: 'urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified',
attribute_value: 'PartnerVal'
)
user_id = Saml::Elements::Attribute.new(
name: "UserId",
format: 'urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified',
attribute_value: name_id
)
time_stamp = Saml::Elements::Attribute.new(
name: "TimeStamp",
format: 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
attribute_value: time.iso8601
)
attribute_statement = Saml::Elements::AttributeStatement.new(
attribute: [partner_id, insured_id, time_stamp])
subject = Saml::Elements::Subject.new(
_name_id: name_id,
recipient: 'https://localhost:3000/saml/consume',
in_response_to: "_#{time}"
)
assertion = Saml::Assertion.new(
subject: subject,
attribute_statement: attribute_statement
)
signed_xml_assertion = Saml::Util.sign_xml(assertion)
response = Saml::Response.new(
status: status,
_id: "_#{time.to_i}",
version: "2.0",
in_response_to: "_#{time}",
assertions: [Saml::Assertion.parse(signed_xml_assertion)]
)
Saml::Util.verify_xml(response.assertion, signed_xml_assertion)
@benoist
Copy link

benoist commented Dec 13, 2013

I've tested this on my machine and the result of the last statement is an assertion.

However the way you're signing now, will not work on the receiving end.

If you just want the assertion signed and send it in a response without signature you have to omit the message.add_signature in the util function.

This code should work better:

assertion = Saml::Assertion.new(valid_args)
response = Saml::Response.new(assertions: [assertion])

assertion.add_signature
document = Xmldsig::SignedDocument.new(response.to_xml)
document.sign do |data, signature_algorithm|
  response.provider.sign(signature_algorithm, data)
end

Doing it this way, will make sure the receiver of the response gets the raw signed message. This includes the correct amount of whitespace in the xml.

@jonathan
Copy link
Author

Nope, that doesn't work either. We have a client trying to validate using .Net code and it always comes back with a bad sig error.

I've tried the samlr lib a little and their validate method kicks out the libsaml created message with an error as well. Only it's validating it against the saml schema xsd. I'm still trying to reduce the problem down to see what exactly is happening and where it's going wrong. Saml is a big standard and there be dragons.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment