Class: Captivus::AuthHMAC
- Inherits:
-
Object
- Object
- Captivus::AuthHMAC
- Includes:
- Headers
- Defined in:
- lib/captivus/auth_hmac.rb,
lib/captivus/auth_hmac/version.rb
Defined Under Namespace
Modules: Headers Classes: CanonicalString
Constant Summary collapse
- VERSION =
"0.0.2"
- @@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, )
146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/captivus/auth_hmac.rb', line 146 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.
194 195 196 197 |
# File 'lib/captivus/auth_hmac.rb', line 194 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.
166 167 168 |
# File 'lib/captivus/auth_hmac.rb', line 166 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.
184 185 186 187 |
# File 'lib/captivus/auth_hmac.rb', line 184 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.
175 176 177 |
# File 'lib/captivus/auth_hmac.rb', line 175 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.
220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/captivus/auth_hmac.rb', line 220 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
246 247 248 |
# File 'lib/captivus/auth_hmac.rb', line 246 def (request, access_key_id, secret) "#{@service_id} #{access_key_id}:#{signature(request, secret)}" end |
#authorization_header(request) ⇒ Object
242 243 244 |
# File 'lib/captivus/auth_hmac.rb', line 242 def (request) find_header(%w(Authorization HTTP_AUTHORIZATION), headers(request)) end |
#canonical_string(request) ⇒ Object
238 239 240 |
# File 'lib/captivus/auth_hmac.rb', line 238 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.
208 209 210 211 212 |
# File 'lib/captivus/auth_hmac.rb', line 208 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
232 233 234 235 236 |
# File 'lib/captivus/auth_hmac.rb', line 232 def signature(request, secret) digest = OpenSSL::Digest::Digest.new('sha1') string = canonical_string(request) Base64.strict_encode64(OpenSSL::HMAC.digest(digest, secret, string)).strip end |