Class: SAML::AuthResponse
- Inherits:
-
Object
- Object
- SAML::AuthResponse
- Includes:
- Onelogin::Saml::Codeing
- Defined in:
- lib/saml/auth_response.rb
Instance Attribute Summary collapse
-
#document ⇒ Object
Returns the value of attribute document.
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#request ⇒ Object
Returns the value of attribute request.
Instance Method Summary collapse
- #build_assertion_content(name_id, assert_id, time_line, sign = nil) ⇒ Object
- #create(name_id) ⇒ Object
- #get_idp_issuer ⇒ Object
- #get_sp_destination ⇒ Object
- #get_sp_response_to ⇒ Object
-
#initialize(request, logger = nil) ⇒ AuthResponse
constructor
A new instance of AuthResponse.
- #make_signature(assertion, assert_id) ⇒ Object
- #response_url(name_id, params = {}) ⇒ Object
- #signature_digest_value(xml) ⇒ Object
- #signature_sign_value(xml) ⇒ Object
- #xml_time_format(time) ⇒ Object
Constructor Details
#initialize(request, logger = nil) ⇒ AuthResponse
Returns a new instance of AuthResponse.
9 10 11 12 13 14 |
# File 'lib/saml/auth_response.rb', line 9 def initialize(request, logger = nil) raise ArgumentError.new("Response cannot be nil") if request.nil? self.logger = logger || ActiveRecord::Base.logger self.request = inflate(decode(request)) self.document = Nokogiri::XML(self.request) end |
Instance Attribute Details
#document ⇒ Object
Returns the value of attribute document.
6 7 8 |
# File 'lib/saml/auth_response.rb', line 6 def document @document end |
#logger ⇒ Object
Returns the value of attribute logger.
6 7 8 |
# File 'lib/saml/auth_response.rb', line 6 def logger @logger end |
#request ⇒ Object
Returns the value of attribute request.
6 7 8 |
# File 'lib/saml/auth_response.rb', line 6 def request @request end |
Instance Method Details
#build_assertion_content(name_id, assert_id, time_line, sign = nil) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/saml/auth_response.rb', line 88 def build_assertion_content(name_id, assert_id, time_line, sign =nil) time_and_ten = xml_time_format(time_line + 10.minutes) time = xml_time_format(time_line) xml = Builder::XmlMarkup.new xml.tag!('saml:Assertion', {"xmlns:saml"=>"urn:oasis:names:tc:SAML:2.0:assertion", "ID"=>assert_id, "Version"=>"2.0", "IssueInstant"=> time}) do xml.tag!("saml:Issuer", get_idp_issuer) xml << sign if sign.present? xml.tag! "saml:Subject" do xml.tag!("saml:NameID", {"Format"=>"urn:oasis:names:tc:SAML:2.0:nameid-format:transient"}, name_id) xml.tag!("saml:SubjectConfirmation", {"Method" => "urn:oasis:names:tc:SAML:2.0:cm:bearer"}) do xml.tag!("saml:SubjectConfirmationData", {"InResponseTo" => get_sp_response_to, "Recipient" => get_sp_destination, "NotOnOrAfter" => time_and_ten}) end end # xml.tag!("saml:Conditions", {"NotBefore" => time, "NotOnOrAfter" => time_and_ten}) do # xml.tag!("saml:AudienceRestriction") do # xml.tag!("saml:Audience", get_sp_audience) # end # end xml.tag!("saml:AuthnStatement", {"AuthnInstant" => time, "SessionIndex" => assert_id}) do xml.tag!("saml:AuthnContext") do xml.tag!("saml:AuthnContextClassRef", "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport") end end end xml.target! end |
#create(name_id) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/saml/auth_response.rb', line 56 def create(name_id) time_line = Time.now.utc request_id = UUID.new.generate assert_id = UUID.new.generate time = xml_time_format(time_line) assertion = build_assertion_content(name_id, assert_id, time_line) # assertion_parsed = Nokogiri::XML(assertion) # assertion_parsed.xpath("//saml:Assertion//saml:Issuer").first.add_next_sibling(make_signature(assertion, assert_id)) response = Builder::XmlMarkup.new response.tag!('samlp:Response', {"xmlns:samlp" => "urn:oasis:names:tc:SAML:2.0:protocol", "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion", "xmlns:ds" => "http://www.w3.org/2000/09/xmldsig#", "ID" => request_id, "Version" => "2.0", "InResponseTo" => get_sp_response_to, "IssueInstant" => time, "Destination" => get_sp_destination}) do response.tag!("saml:Issuer", get_idp_issuer) response.tag!("samlp:Status") do response.tag!("samlp:StatusCode", "Value" => "urn:oasis:names:tc:SAML:2.0:status:Success") end response << build_assertion_content(name_id, assert_id, time_line, make_signature(assertion, assert_id)) #todo if insert node this way - need to canonicalize. nokogiri 1.4.4 has no possibility to do it. only it's branch can do it:( # response << assertion_parsed.xpath("//saml:Assertion").canonicalize.to_s end response.target! end |
#get_idp_issuer ⇒ Object
24 25 26 |
# File 'lib/saml/auth_response.rb', line 24 def get_idp_issuer Settings.host end |
#get_sp_destination ⇒ Object
20 21 22 |
# File 'lib/saml/auth_response.rb', line 20 def get_sp_destination Settings.sso.sp_destination end |
#get_sp_response_to ⇒ Object
16 17 18 |
# File 'lib/saml/auth_response.rb', line 16 def get_sp_response_to document.xpath("//samlp:AuthnRequest").first["ID"] end |
#make_signature(assertion, assert_id) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/saml/auth_response.rb', line 121 def make_signature(assertion, assert_id) certificate = File.read("#{Rails.root}/config/cert/#{Rails.env}/idp.ignite.com.crt") # certificate = File.read("#{Rails.root}/config/cert/development/IdpCertificate.cer") certificate.gsub!("-----BEGIN CERTIFICATE-----", "") certificate.gsub!("-----END CERTIFICATE-----", "") sign_info_xml_builder = Builder::XmlMarkup.new sign_info_xml_builder.tag!("ds:SignedInfo", {"xmlns:ds"=>"http://www.w3.org/2000/09/xmldsig#"}) do sign_info_xml_builder.tag!("ds:CanonicalizationMethod", {"Algorithm"=>"http://www.w3.org/2001/10/xml-exc-c14n#"}) sign_info_xml_builder.tag!("ds:SignatureMethod", {"Algorithm"=>"http://www.w3.org/2000/09/xmldsig#rsa-sha1"}) sign_info_xml_builder.tag!("ds:Reference", {"URI" => "##{assert_id}"}) do sign_info_xml_builder.tag!("ds:Transforms") do sign_info_xml_builder.tag!("ds:Transform", {"Algorithm"=>"http://www.w3.org/2000/09/xmldsig#enveloped-signature"}) sign_info_xml_builder.tag!("ds:Transform", {"Algorithm"=>"http://www.w3.org/2001/10/xml-exc-c14n#"}) end sign_info_xml_builder.tag!("ds:DigestMethod", {"Algorithm"=>"http://www.w3.org/2000/09/xmldsig#sha1"}) sign_info_xml_builder.tag!("ds:DigestValue", {"URI" => assert_id}, signature_digest_value(assertion)) end end sign_info_xml = sign_info_xml_builder.target! s_value = signature_sign_value(sign_info_xml) xml = Builder::XmlMarkup.new xml.tag!('ds:Signature', {"xmlns:ds" => "http://www.w3.org/2000/09/xmldsig#"}) do xml << sign_info_xml xml.tag!("ds:SignatureValue", {"xmlns:ds" => "http://www.w3.org/2000/09/xmldsig#"}, s_value) xml.tag!('ds:KeyInfo') do xml.tag!('ds:X509Data') do xml.tag!('ds:X509Certificate', certificate) end end end xml.target! end |
#response_url(name_id, params = {}) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/saml/auth_response.rb', line 39 def response_url(name_id, params={}) prepared_result = create(name_id) base64_request = encode(prepared_result) # deflated_request = deflate(create(name_id)) # base64_request = encode(deflated_request) base64_request.gsub!(/\s/,"") # encoded_response = escape(base64_request) # # encoded_response ## request_params = "?SAMLResponse=" + encoded_response # # params.each_pair do |key, value| # request_params << "&#{key}=#{escape(value.to_s)}" # end # Settings.sso.sp_destination+ request_params end |
#signature_digest_value(xml) ⇒ Object
169 170 171 172 173 174 |
# File 'lib/saml/auth_response.rb', line 169 def signature_digest_value(xml) document = XMLSecurity::SignedDocument.new(xml) canoner = XML::Util::XmlCanonicalizer.new(false, true) canon_hashed_element = canoner.canonicalize(document) Base64.encode64(Digest::SHA1.digest(canon_hashed_element)).chomp end |
#signature_sign_value(xml) ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/saml/auth_response.rb', line 156 def signature_sign_value(xml) document = XMLSecurity::SignedDocument.new(xml) canoner = XML::Util::XmlCanonicalizer.new(false, true) signed_info_element = REXML::XPath.first(document, "//ds:SignedInfo", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}) canon_string = canoner.canonicalize(signed_info_element) # private_key = OpenSSL::PKey::RSA.new(File.read("#{Rails.root}/config/cert/#{Rails.env}/idp.ignite.com.key")) #private_key = OpenSSL::PKey::RSA.new(File.read("#{Rails.root}/config/cert/development/SPkey.key")) private_key = OpenSSL::PKey::RSA.new(File.read("#{Rails.root}/config/cert/development/IgniteKeyDecrypted.key")) sig = private_key.sign(OpenSSL::Digest::SHA1.new, canon_string) Base64.encode64(sig).chomp end |
#xml_time_format(time) ⇒ Object
34 35 36 |
# File 'lib/saml/auth_response.rb', line 34 def xml_time_format time time.strftime("%Y-%m-%dT%H:%M:%SZ") end |