class OmniAuth::Strategies::Signicat
OmniAuth
Strategy for authenticating with Signicat
based identity solutions
Constants
- XML_DS_NS
Public Class Methods
inherited(subclass)
click to toggle source
# File lib/omniauth/strategies/signicat.rb, line 14 def self.inherited(subclass) OmniAuth::Strategy.included(subclass) end
Public Instance Methods
callback_phase()
click to toggle source
Calls superclass method
# File lib/omniauth/strategies/signicat.rb, line 30 def callback_phase unless request.params['SAMLResponse'] raise OmniAuth::Strategies::Signicat::ValidationError, 'SAML response missing' end saml_response = Base64.decode64(request.params['SAMLResponse']) xml = Nokogiri.parse(saml_response) verify_signature!(xml) assign_attributes(xml) super rescue OmniAuth::Strategies::Signicat::ValidationError fail!(:invalid_ticket, $ERROR_INFO) end
request_phase()
click to toggle source
# File lib/omniauth/strategies/signicat.rb, line 26 def request_phase redirect(target_url) end
target_url()
click to toggle source
# File lib/omniauth/strategies/signicat.rb, line 45 def target_url [ "https://#{options[:env]}.signicat.com", "/std/method/#{options[:service]}", "?id=#{options[:method]}:#{options[:profile]}:#{options[:language]}", "&#{prefilled_query_params}", "&target=#{CGI.escape(callback_url)}" ].join('') end
Private Instance Methods
assign_attributes(xml)
click to toggle source
# File lib/omniauth/strategies/signicat.rb, line 112 def assign_attributes(xml) @attributes = {} xml.xpath('//saml:Attribute').each do |attr_node| key = attr_node['AttributeName'] value = attr_node.text @attributes[key] = value end @name_id = @attributes['unique-id'] end
expected_cert_subject()
click to toggle source
# File lib/omniauth/strategies/signicat.rb, line 122 def expected_cert_subject if options[:env] == 'id' '/C=NO/ST=Norway/L=Trondheim/O=Signicat/OU=Signicat/CN=id.signicat.com/std' else '/C=NO/ST=Norway/L=Trondheim/O=Signicat/OU=Signicat/CN=test.signicat.com/std' end end
extract_public_key(xml)
click to toggle source
# File lib/omniauth/strategies/signicat.rb, line 90 def extract_public_key(xml) raw_cert = xml.xpath('//ds:X509Certificate/text()', 'ds' => XML_DS_NS).text cert = OpenSSL::X509::Certificate.new(Base64.decode64(raw_cert)) if cert.subject.to_s != expected_cert_subject raise OmniAuth::Strategies::Signicat::ValidationError, 'Invalid certificate' end cert.public_key end
extract_signature(xml)
click to toggle source
# File lib/omniauth/strategies/signicat.rb, line 107 def extract_signature(xml) raw_signature = xml.xpath('//ds:SignatureValue', 'ds' => XML_DS_NS).text Base64.decode64(raw_signature) end
extract_signed_info(xml)
click to toggle source
# File lib/omniauth/strategies/signicat.rb, line 99 def extract_signed_info(xml) noko_sig_element = xml.at_xpath('//ds:Signature', 'ds' => XML_DS_NS) noko_signed_info_element = noko_sig_element.at_xpath('./ds:SignedInfo', 'ds' => XML_DS_NS) canon_algorithm = Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0 noko_signed_info_element.canonicalize(canon_algorithm) end
prefilled_query_params()
click to toggle source
# File lib/omniauth/strategies/signicat.rb, line 69 def prefilled_query_params options.fetch(:prefilled, {}).map do |key, value| "prefilled.#{key}=#{value}" end.join('&') end
verify_signature!(xml)
click to toggle source
# File lib/omniauth/strategies/signicat.rb, line 75 def verify_signature!(xml) key = extract_public_key(xml) begin signed_info = extract_signed_info(xml) signature = extract_signature(xml) return if key.verify(OpenSSL::Digest::SHA1.new, signature, signed_info) raise OmniAuth::Strategies::Signicat::ValidationError, 'Invalid signature (SHA1)' rescue OmniAuth::Strategies::Signicat::ValidationError return if key.verify(OpenSSL::Digest::SHA256.new, signature, signed_info) raise OmniAuth::Strategies::Signicat::ValidationError, 'Invalid signature (SHA256)' end end