From f13f5f7a83c4e26ea2b02341bd848f29df072b8e Mon Sep 17 00:00:00 2001 From: Florian Wininger Date: Mon, 22 Feb 2016 22:23:17 +0100 Subject: [PATCH] Forward the Hmac digest method in the Header HMAC_METHOD --- lib/api_auth/base.rb | 17 +++++++++++------ spec/api_auth_spec.rb | 6 +++--- spec/railtie_spec.rb | 4 ++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/api_auth/base.rb b/lib/api_auth/base.rb index 5d652bbe..92319208 100644 --- a/lib/api_auth/base.rb +++ b/lib/api_auth/base.rb @@ -21,7 +21,7 @@ class << self # # secret_key: assigned secret key that is known to both parties def sign!(request, access_id, secret_key, options = {}) - options = { :override_http_method => nil, :with_http_method => false, :digest => 'sha1' }.merge(options) + options = { :override_http_method => nil, :with_http_method => false, :digest => 'SHA1' }.merge(options) headers = Headers.new(request) headers.calculate_md5 headers.set_date @@ -32,9 +32,11 @@ def sign!(request, access_id, secret_key, options = {}) # secret key. Returns true if the request is authentic and false otherwise. def authentic?(request, secret_key, options = {}) return false if secret_key.nil? - options = { :override_http_method => nil, :digest => 'sha1' }.merge(options) + + options = { :override_http_method => nil }.merge(options) headers = Headers.new(request) + if headers.md5_mismatch? false elsif !signatures_match?(headers, secret_key, options) @@ -50,7 +52,7 @@ def authentic?(request, secret_key, options = {}) def access_id(request) headers = Headers.new(request) if match_data = parse_auth_header(headers.authorization_header) - return match_data[1] + return match_data[2] end nil @@ -67,7 +69,7 @@ def generate_secret_key private - AUTH_HEADER_PATTERN = /APIAuth ([^:]+):(.+)$/ + AUTH_HEADER_PATTERN = /APIAuth(?:-HMAC-(MD[245]|SHA(?:1|224|256|384|512)*))? ([^:]+):(.+)$/ def request_too_old?(headers) # 900 seconds is 15 minutes @@ -81,7 +83,10 @@ def signatures_match?(headers, secret_key, options) match_data = parse_auth_header(headers.authorization_header) return false unless match_data - header_sig = match_data[2] + digest = match_data[1].blank? ? 'SHA1' : match_data[1].upcase + options = { :digest => digest }.merge(options) + + header_sig = match_data[3] calculated_sig_no_http = hmac_signature(headers, secret_key, options.merge(:with_http_method => false)) calculated_sig_with_http = hmac_signature(headers, secret_key, options.merge(:with_http_method => true)) @@ -99,7 +104,7 @@ def hmac_signature(headers, secret_key, options) end def auth_header(headers, access_id, secret_key, options) - "APIAuth #{access_id}:#{hmac_signature(headers, secret_key, options)}" + "APIAuth-HMAC-#{options[:digest].upcase} #{access_id}:#{hmac_signature(headers, secret_key, options)}" end def parse_auth_header(auth_header) diff --git a/spec/api_auth_spec.rb b/spec/api_auth_spec.rb index 37005e42..5c9b7a72 100644 --- a/spec/api_auth_spec.rb +++ b/spec/api_auth_spec.rb @@ -52,7 +52,7 @@ def hmac(secret_key, request, canonical_string = nil, digest = 'sha1') it 'calculates the hmac_signature as expected' do ApiAuth.sign!(request, '1044', '123') signature = hmac('123', request) - expect(request.headers['Authorization']).to eq("APIAuth 1044:#{signature}") + expect(request.headers['Authorization']).to eq("APIAuth-HMAC-SHA1 1044:#{signature}") end context 'when passed the with_http_method option' do @@ -69,7 +69,7 @@ def hmac(secret_key, request, canonical_string = nil, digest = 'sha1') it 'calculates the hmac_signature with http method' do ApiAuth.sign!(request, '1044', '123', :with_http_method => true) signature = hmac('123', request, canonical_string) - expect(request['Authorization']).to eq("APIAuth 1044:#{signature}") + expect(request['Authorization']).to eq("APIAuth-HMAC-SHA1 1044:#{signature}") end end @@ -87,7 +87,7 @@ def hmac(secret_key, request, canonical_string = nil, digest = 'sha1') it 'calculates the hmac_signature with http method' do ApiAuth.sign!(request, '1044', '123', :with_http_method => true, :digest => 'sha256') signature = hmac('123', request, canonical_string, 'sha256') - expect(request['Authorization']).to eq("APIAuth 1044:#{signature}") + expect(request['Authorization']).to eq("APIAuth-HMAC-SHA256 1044:#{signature}") end end end diff --git a/spec/railtie_spec.rb b/spec/railtie_spec.rb index 72418b6a..70458431 100644 --- a/spec/railtie_spec.rb +++ b/spec/railtie_spec.rb @@ -116,7 +116,7 @@ class TestResource < ActiveResource::Base ActiveResource::HttpMock.respond_to do |mock| mock.get '/test_resources/1.xml', { - 'Authorization' => 'APIAuth 1044:IbTx7VzSOGU55HNbV4y2jZDnVis=', + 'Authorization' => 'APIAuth-HMAC-SHA1 1044:IbTx7VzSOGU55HNbV4y2jZDnVis=', 'Accept' => 'application/xml', 'DATE' => 'Mon, 23 Jan 1984 03:29:56 GMT' }, @@ -139,7 +139,7 @@ class TestResourceForHttpMethod < ActiveResource::Base ActiveResource::HttpMock.respond_to do |mock| mock.get '/test_resource_for_http_methods/1.xml', { - 'Authorization' => 'APIAuth 1044:Gq190cxgKm7oWH1fc+y8+wmD9ts=', + 'Authorization' => 'APIAuth-HMAC-SHA1 1044:Gq190cxgKm7oWH1fc+y8+wmD9ts=', 'Accept' => 'application/xml', 'DATE' => 'Mon, 23 Jan 1984 03:29:56 GMT' },