Class: CrashLog::AuthHMAC
- Inherits:
-
Object
- Object
- CrashLog::AuthHMAC
- Includes:
- Headers
- Defined in:
- lib/crash_log/auth_hmac.rb,
lib/crash_log/auth_hmac/version.rb
Defined Under Namespace
Modules: Headers Classes: CanonicalString
Constant Summary collapse
- VERSION =
"1.1.7"
- @@default_signature_class =
CanonicalString
Class Method Summary collapse
-
.authenticated?(request, access_key_id, secret, options) ⇒ Boolean
Authenticates a request using HMAC.
-
.canonical_string(request, options = nil) ⇒ Object
Generates canonical signing string for given request.
-
.sign!(request, access_key_id, secret, options = nil) ⇒ Object
Signs a request using a given access key id and secret.
-
.signature(request, secret, options = nil) ⇒ Object
Generates signature string for a given secret.
Instance Method Summary collapse
-
#authenticated?(request) ⇒ Boolean
Authenticates a request using HMAC.
- #authorization(request, access_key_id, secret) ⇒ Object
- #authorization_header(request) ⇒ Object
- #canonical_string(request) ⇒ Object
-
#initialize(credential_store, options = nil) ⇒ AuthHMAC
constructor
Create an AuthHMAC instance using the given credential store.
-
#sign!(request, access_key_id) ⇒ Object
Signs a request using the access_key_id and the secret associated with that id in the credential store.
- #signature(request, secret) ⇒ Object
Methods included from Headers
Constructor Details
#initialize(credential_store, options = nil) ⇒ AuthHMAC
Create an AuthHMAC instance using the given credential store
Credential Store:
-
Credential store must respond to the [] method and return a secret for access key id
Options: Override default options
-
:service_id
- Service ID used in the AUTHORIZATION header string. Default is AuthHMAC. -
:signature_method
- Proc object that takes request and produces the signature stringused for authentication. Default is CanonicalString.
Examples:
my_hmac = AuthHMAC.new('access_id1' => 'secret1', 'access_id2' => 'secret2')
cred_store = { 'access_id1' => 'secret1', 'access_id2' => 'secret2' }
= { :service_id => 'MyApp', :signature_method => lambda { |r| MyRequestString.new(r) } }
my_hmac = AuthHMAC.new(cred_store, )
145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/crash_log/auth_hmac.rb', line 145 def initialize(credential_store, = nil) @credential_store = credential_store # Defaults @service_id = self.class.name.split(/::/).last @signature_class = @@default_signature_class unless .nil? @service_id = [:service_id] if .key?(:service_id) @signature_class = [:signature] if .key?(:signature) && [:signature].is_a?(Class) end @signature_method = lambda { |r| @signature_class.send(:new, r) } end |
Class Method Details
.authenticated?(request, access_key_id, secret, options) ⇒ Boolean
Authenticates a request using HMAC
Supports same options as AuthHMAC.initialize for overriding service_id and signature method.
193 194 195 196 |
# File 'lib/crash_log/auth_hmac.rb', line 193 def self.authenticated?(request, access_key_id, secret, ) credentials = { access_key_id => secret } self.new(credentials, ).authenticated?(request) end |
.canonical_string(request, options = nil) ⇒ Object
Generates canonical signing string for given request
Supports same options as AuthHMAC.initialize for overriding service_id and signature method.
165 166 167 |
# File 'lib/crash_log/auth_hmac.rb', line 165 def self.canonical_string(request, = nil) self.new(nil, ).canonical_string(request) end |
.sign!(request, access_key_id, secret, options = nil) ⇒ Object
Signs a request using a given access key id and secret.
Supports same options as AuthHMAC.initialize for overriding service_id and signature method.
183 184 185 186 |
# File 'lib/crash_log/auth_hmac.rb', line 183 def self.sign!(request, access_key_id, secret, = nil) credentials = { access_key_id => secret } self.new(credentials, ).sign!(request, access_key_id) end |
.signature(request, secret, options = nil) ⇒ Object
Generates signature string for a given secret
Supports same options as AuthHMAC.initialize for overriding service_id and signature method.
174 175 176 |
# File 'lib/crash_log/auth_hmac.rb', line 174 def self.signature(request, secret, = nil) self.new(nil, ).signature(request, secret) end |
Instance Method Details
#authenticated?(request) ⇒ Boolean
Authenticates a request using HMAC
Returns true if the request has an AuthHMAC Authorization header and the access id and HMAC match an id and HMAC produced for the secret in the credential store. Otherwise returns false.
219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/crash_log/auth_hmac.rb', line 219 def authenticated?(request) rx = Regexp.new("#{@service_id} ([^:]+):(.+)$") if md = rx.match((request)) access_key_id = md[1] hmac = md[2] secret = @credential_store[access_key_id] !secret.nil? && hmac == signature(request, secret) else false end end |
#authorization(request, access_key_id, secret) ⇒ Object
247 248 249 |
# File 'lib/crash_log/auth_hmac.rb', line 247 def (request, access_key_id, secret) "#{@service_id} #{access_key_id}:#{signature(request, secret)}" end |
#authorization_header(request) ⇒ Object
243 244 245 |
# File 'lib/crash_log/auth_hmac.rb', line 243 def (request) find_header(%w(Authorization HTTP_AUTHORIZATION), headers(request)) end |
#canonical_string(request) ⇒ Object
239 240 241 |
# File 'lib/crash_log/auth_hmac.rb', line 239 def canonical_string(request) @signature_method.call(request) end |
#sign!(request, access_key_id) ⇒ Object
Signs a request using the access_key_id and the secret associated with that id in the credential store.
Signing a requests adds an Authorization header to the request in the format:
<service_id> <access_key_id>:<signature>
where <signature> is the Base64 encoded HMAC-SHA1 of the CanonicalString and the secret.
207 208 209 210 211 |
# File 'lib/crash_log/auth_hmac.rb', line 207 def sign!(request, access_key_id) secret = @credential_store[access_key_id] raise ArgumentError, "No secret found for key id '#{access_key_id}'" if secret.nil? request['Authorization'] = (request, access_key_id, secret) end |
#signature(request, secret) ⇒ Object
231 232 233 234 235 236 237 |
# File 'lib/crash_log/auth_hmac.rb', line 231 def signature(request, secret) digest = OpenSSL::Digest::Digest.new('sha1') string = canonical_string(request) hmac = OpenSSL::HMAC.digest(digest, secret, string) encoded_signature = Base64.encode64(hmac) encoded_signature.gsub(/\n/, '').strip end |