warden-hmac-authentication 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +2 -1
- data/bin/warden-hmac-authentication +64 -12
- data/lib/faraday/request/hmac.rb +9 -8
- data/lib/faraday/request/hmac.rb~ +55 -0
- metadata +160 -159
data/README.md
CHANGED
@@ -178,7 +178,8 @@ Some headers are optional but should be included in the signature of the request
|
|
178
178
|
includes `Content-MD5` and `Content-Type`. The list of optional headers can be configured using the `:optional_headers` config option.
|
179
179
|
Optional headers are always included in the canonical representation if they are found in the request and not blank. Optional headers
|
180
180
|
will be included in the canonical representation for query-based authentication if they are present in the request so be careful
|
181
|
-
not to include any header that is out of your clients control.
|
181
|
+
not to include any header that is out of your clients control. Optional headers are currently not validated in any other way, that is
|
182
|
+
the strategy does not check that they actually match the provided request body. This check is currently up to the application.
|
182
183
|
|
183
184
|
## Date and TTL
|
184
185
|
|
@@ -1,16 +1,68 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# This file was generated by Bundler.
|
4
|
-
#
|
5
|
-
# The application 'warden-hmac-authentication' is installed as part of a gem, and
|
6
|
-
# this file is here to facilitate running it.
|
7
|
-
#
|
8
2
|
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
begin
|
4
|
+
require 'trollop'
|
5
|
+
rescue LoadError => e
|
6
|
+
puts ""
|
7
|
+
puts ""
|
8
|
+
puts "============= ERROR ================"
|
9
|
+
puts ""
|
10
|
+
puts "You need trollop installed or in your gemfile to use the signer"
|
11
|
+
puts ""
|
12
|
+
puts "============= ERROR ================"
|
13
|
+
puts ""
|
14
|
+
puts ""
|
15
|
+
exit(-1)
|
16
|
+
end
|
12
17
|
|
13
|
-
require '
|
14
|
-
require 'bundler/setup'
|
18
|
+
require 'hmac/signer'
|
15
19
|
|
16
|
-
|
20
|
+
opts = Trollop::options do
|
21
|
+
|
22
|
+
version "warden-hmac-sign 0.3.0 (c) 2011 Felix Gilcher, Florian Gilcher"
|
23
|
+
banner <<-EOS
|
24
|
+
warden-hmac-authentication is used to create and validate signed urls for
|
25
|
+
usage with the HMAC authentication scheme used by
|
26
|
+
https://github.com/Asquera/warden-hmac-authentication
|
27
|
+
|
28
|
+
Usage:
|
29
|
+
warden-hmac-authentication [options] <command> url
|
30
|
+
|
31
|
+
where command is one of
|
32
|
+
|
33
|
+
sign: signs the given url
|
34
|
+
validate: validates the given url
|
35
|
+
|
36
|
+
and where [options] are:
|
37
|
+
|
38
|
+
EOS
|
39
|
+
|
40
|
+
opt :algorithm, "The hashing algorithm to use for the HMAC", :type => :string, :default => "sha1"
|
41
|
+
opt :secret, "The shared secret for the HMAC", :type => :string, :required => true
|
42
|
+
opt :"auth-param", "The name for the auth param in the url", :default => "auth"
|
43
|
+
opt :"date", "The date to use for the signature (defaults to now)"
|
44
|
+
end
|
45
|
+
|
46
|
+
cmd = ARGV.shift
|
47
|
+
Trollop::die "You must give a command" if cmd.nil?
|
48
|
+
Trollop::die "You command must be one of [sign, validate]" unless ["sign", "validate"].include? cmd
|
49
|
+
Trollop::die "You must provide a URL" if ARGV.empty?
|
50
|
+
url = ARGV.shift
|
51
|
+
|
52
|
+
secret = opts.delete(:secret)
|
53
|
+
algorithm = opts.delete(:algorithm)
|
54
|
+
|
55
|
+
signer = HMAC::Signer.new(algorithm)
|
56
|
+
|
57
|
+
if "sign" == cmd
|
58
|
+
puts signer.sign_url(url, secret, opts)
|
59
|
+
else
|
60
|
+
success = signer.validate_url_signature(url, secret, opts)
|
61
|
+
if success
|
62
|
+
puts "URL #{url} is valid"
|
63
|
+
exit 0
|
64
|
+
else
|
65
|
+
puts "URL #{url} does not contain a valid signature"
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
end
|
data/lib/faraday/request/hmac.rb
CHANGED
@@ -3,7 +3,7 @@ require 'hmac/signer'
|
|
3
3
|
|
4
4
|
module Faraday
|
5
5
|
class Request::Hmac < Faraday::Middleware
|
6
|
-
|
6
|
+
|
7
7
|
# create a new Hmac middleware instance
|
8
8
|
#
|
9
9
|
# @param [Object] app The url of the request
|
@@ -13,7 +13,7 @@ module Faraday
|
|
13
13
|
# @option options [String] :nonce ('') The nonce to use in the signature
|
14
14
|
# @option options [String, #strftime] :date (Time.now) The date to use in the signature
|
15
15
|
# @option options [Hash] :headers ({}) A list of optional headers to include in the signature
|
16
|
-
#
|
16
|
+
#
|
17
17
|
# @option options [String] :auth_scheme ('HMAC') The name of the authorization scheme used in the Authorization header and to construct various header-names
|
18
18
|
# @option options [String] :auth_param ('auth') The name of the authentication param to use for query based authentication
|
19
19
|
# @option options [Hash] :extra_auth_params ({}) Additional parameters to inject in the auth parameter. This parameter is ignored unless :query_based evaluates to true.
|
@@ -27,21 +27,22 @@ module Faraday
|
|
27
27
|
def initialize(app, secret, options = {})
|
28
28
|
@app, @secret, @options, @query_values = app, secret, options
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
def call(env)
|
32
32
|
sign(env)
|
33
33
|
@app.call(env)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def sign(env)
|
37
37
|
signer = HMAC::Signer.new
|
38
38
|
url = env[:url]
|
39
|
-
|
40
|
-
|
39
|
+
method = env[:method]
|
40
|
+
headers, url = *signer.sign_request(url, @secret, @options.merge(:method => env[:method]))
|
41
|
+
|
41
42
|
env[:request_headers] = (env[:request_headers] || {}).merge(headers)
|
42
43
|
env[:url] = URI.parse(url)
|
43
44
|
env
|
44
45
|
end
|
45
|
-
|
46
|
+
|
46
47
|
end
|
47
|
-
end
|
48
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'hmac/signer'
|
3
|
+
|
4
|
+
module Faraday
|
5
|
+
class Request::Hmac < Faraday::Middleware
|
6
|
+
|
7
|
+
# create a new Hmac middleware instance
|
8
|
+
#
|
9
|
+
# @param [Object] app The url of the request
|
10
|
+
# @param [String] secret The shared secret for the signature
|
11
|
+
# @param [Hash] options Options for the signature generation
|
12
|
+
#
|
13
|
+
# @option options [String] :nonce ('') The nonce to use in the signature
|
14
|
+
# @option options [String, #strftime] :date (Time.now) The date to use in the signature
|
15
|
+
# @option options [Hash] :headers ({}) A list of optional headers to include in the signature
|
16
|
+
#
|
17
|
+
# @option options [String] :auth_scheme ('HMAC') The name of the authorization scheme used in the Authorization header and to construct various header-names
|
18
|
+
# @option options [String] :auth_param ('auth') The name of the authentication param to use for query based authentication
|
19
|
+
# @option options [Hash] :extra_auth_params ({}) Additional parameters to inject in the auth parameter. This parameter is ignored unless :query_based evaluates to true.
|
20
|
+
# @option options [String] :auth_header ('Authorization') The name of the authorization header to use
|
21
|
+
# @option options [String] :auth_header_format ('%{auth_scheme} %{signature}') The format of the authorization header. Will be interpolated with the given options and the signature.
|
22
|
+
# @option options [String] :nonce_header ('X-#{auth_scheme}-Nonce') The header name for the request nonce
|
23
|
+
# @option options [String] :alternate_date_header ('X-#{auth_scheme}-Date') The header name for the alternate date header
|
24
|
+
# @option options [Bool] :query_based (false) Whether to use query based authentication
|
25
|
+
# @option options [Bool] :use_alternate_date_header (false) Use the alternate date header instead of `Date`
|
26
|
+
#
|
27
|
+
def initialize(app, secret, options = {})
|
28
|
+
@app, @secret, @options, @query_values = app, secret, options
|
29
|
+
end
|
30
|
+
|
31
|
+
def call(env)
|
32
|
+
sign(env)
|
33
|
+
@app.call(env)
|
34
|
+
end
|
35
|
+
|
36
|
+
def sign(env)
|
37
|
+
signer = HMAC::Signer.new
|
38
|
+
url = env[:url]
|
39
|
+
<<<<<<< HEAD
|
40
|
+
method = env[:method]
|
41
|
+
headers, url = *signer.sign_request(url, @secret, @options.merge(:method => env[:method]))
|
42
|
+
=======
|
43
|
+
|
44
|
+
signer_options = { :method => env[:method] }.merge @options
|
45
|
+
|
46
|
+
headers, url = *signer.sign_request(url, @secret, signer_options)
|
47
|
+
>>>>>>> fc6d1ee3917881a31a9f68a37ece8f630a896840
|
48
|
+
|
49
|
+
env[:request_headers] = (env[:request_headers] || {}).merge(headers)
|
50
|
+
env[:url] = URI.parse(url)
|
51
|
+
env
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
metadata
CHANGED
@@ -1,211 +1,212 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: warden-hmac-authentication
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 6
|
9
|
+
- 4
|
10
|
+
version: 0.6.4
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Felix Gilcher
|
9
14
|
- Florian Gilcher
|
10
15
|
autorequire:
|
11
16
|
bindir: bin
|
12
17
|
cert_chain: []
|
13
|
-
|
14
|
-
|
15
|
-
|
18
|
+
|
19
|
+
date: 2013-04-08 00:00:00 +02:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
16
23
|
name: rack
|
17
|
-
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
|
-
requirements:
|
20
|
-
- - ! '>='
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '0'
|
23
|
-
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
|
26
|
-
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
none: false
|
35
|
-
requirements:
|
36
|
-
- - ! '>='
|
37
|
-
- !ruby/object:Gem::Version
|
38
|
-
version: '0'
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
version: "0"
|
39
34
|
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: warden
|
40
38
|
prerelease: false
|
41
|
-
|
42
|
-
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
|
47
|
-
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
48
51
|
name: rake
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
|
-
requirements:
|
52
|
-
- - ! '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
type: :development
|
56
52
|
prerelease: false
|
57
|
-
|
58
|
-
none: false
|
59
|
-
requirements:
|
60
|
-
- -
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
none: false
|
67
|
-
requirements:
|
68
|
-
- - ! '>='
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
version: '0'
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
71
62
|
type: :development
|
63
|
+
version_requirements: *id003
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: rack-test
|
72
66
|
prerelease: false
|
73
|
-
|
74
|
-
none: false
|
75
|
-
requirements:
|
76
|
-
- -
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
none: false
|
83
|
-
requirements:
|
84
|
-
- - ! '>='
|
85
|
-
- !ruby/object:Gem::Version
|
86
|
-
version: '0'
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
version: "0"
|
87
76
|
type: :development
|
77
|
+
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: riot
|
88
80
|
prerelease: false
|
89
|
-
|
90
|
-
none: false
|
91
|
-
requirements:
|
92
|
-
- -
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
none: false
|
99
|
-
requirements:
|
100
|
-
- - ! '>='
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '0'
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
103
90
|
type: :development
|
91
|
+
version_requirements: *id005
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: timecop
|
104
94
|
prerelease: false
|
105
|
-
|
106
|
-
none: false
|
107
|
-
requirements:
|
108
|
-
- -
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
none: false
|
115
|
-
requirements:
|
116
|
-
- - ! '>='
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: '0'
|
95
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
hash: 3
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
version: "0"
|
119
104
|
type: :development
|
105
|
+
version_requirements: *id006
|
106
|
+
- !ruby/object:Gem::Dependency
|
107
|
+
name: simplecov
|
120
108
|
prerelease: false
|
121
|
-
|
122
|
-
none: false
|
123
|
-
requirements:
|
124
|
-
- -
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
none: false
|
131
|
-
requirements:
|
132
|
-
- - ! '>='
|
133
|
-
- !ruby/object:Gem::Version
|
134
|
-
version: '0'
|
109
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
hash: 3
|
115
|
+
segments:
|
116
|
+
- 0
|
117
|
+
version: "0"
|
135
118
|
type: :development
|
119
|
+
version_requirements: *id007
|
120
|
+
- !ruby/object:Gem::Dependency
|
121
|
+
name: simplecov-html
|
136
122
|
prerelease: false
|
137
|
-
|
138
|
-
none: false
|
139
|
-
requirements:
|
140
|
-
- -
|
141
|
-
- !ruby/object:Gem::Version
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
none: false
|
147
|
-
requirements:
|
148
|
-
- - ! '>='
|
149
|
-
- !ruby/object:Gem::Version
|
150
|
-
version: '0'
|
123
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
hash: 3
|
129
|
+
segments:
|
130
|
+
- 0
|
131
|
+
version: "0"
|
151
132
|
type: :development
|
133
|
+
version_requirements: *id008
|
134
|
+
- !ruby/object:Gem::Dependency
|
135
|
+
name: trollop
|
152
136
|
prerelease: false
|
153
|
-
|
154
|
-
none: false
|
155
|
-
requirements:
|
156
|
-
- -
|
157
|
-
- !ruby/object:Gem::Version
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
137
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
hash: 3
|
143
|
+
segments:
|
144
|
+
- 0
|
145
|
+
version: "0"
|
146
|
+
type: :development
|
147
|
+
version_requirements: *id009
|
148
|
+
description: |-
|
149
|
+
This gem provides request authentication via [HMAC](http://en.wikipedia.org/wiki/Hmac). The main usage is request based, noninteractive
|
150
|
+
authentication for API implementations. Two strategies are supported that differ mainly in how the authentication information is
|
151
|
+
transferred to the server: One header-based authentication method and one query-based. The authentication scheme is in some parts based
|
152
|
+
on ideas laid out in this article and the following discussion:
|
153
|
+
http://broadcast.oreilly.com/2009/12/principles-for-standardized-rest-authentication.html
|
154
|
+
|
155
|
+
The gem also provides a small helper class that can be used to generate request signatures.
|
156
|
+
email:
|
168
157
|
- felix.gilcher@asquera.de
|
169
158
|
- florian.gilcher@asquera.de
|
170
|
-
executables:
|
159
|
+
executables:
|
171
160
|
- warden-hmac-authentication
|
172
161
|
extensions: []
|
162
|
+
|
173
163
|
extra_rdoc_files: []
|
174
|
-
|
164
|
+
|
165
|
+
files:
|
175
166
|
- README.md
|
176
167
|
- Rakefile
|
177
168
|
- LICENSE
|
178
169
|
- lib/faraday/request/hmac.rb
|
170
|
+
- lib/faraday/request/hmac.rb~
|
179
171
|
- lib/hmac/signer.rb
|
180
172
|
- lib/hmac/strategies/base.rb
|
181
173
|
- lib/hmac/strategies/header.rb
|
182
174
|
- lib/hmac/strategies/query.rb
|
183
175
|
- lib/hmac/string/jruby.rb
|
184
|
-
-
|
185
|
-
|
176
|
+
- bin/warden-hmac-authentication
|
177
|
+
has_rdoc: true
|
186
178
|
homepage: https://github.com/Asquera/warden-hmac-authentication
|
187
179
|
licenses: []
|
180
|
+
|
188
181
|
post_install_message:
|
189
182
|
rdoc_options: []
|
190
|
-
|
183
|
+
|
184
|
+
require_paths:
|
191
185
|
- lib
|
192
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
186
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
193
187
|
none: false
|
194
|
-
requirements:
|
195
|
-
- -
|
196
|
-
- !ruby/object:Gem::Version
|
197
|
-
|
198
|
-
|
188
|
+
requirements:
|
189
|
+
- - ">="
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
hash: 3
|
192
|
+
segments:
|
193
|
+
- 0
|
194
|
+
version: "0"
|
195
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
199
196
|
none: false
|
200
|
-
requirements:
|
201
|
-
- -
|
202
|
-
- !ruby/object:Gem::Version
|
203
|
-
|
197
|
+
requirements:
|
198
|
+
- - ">="
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
hash: 3
|
201
|
+
segments:
|
202
|
+
- 0
|
203
|
+
version: "0"
|
204
204
|
requirements: []
|
205
|
+
|
205
206
|
rubyforge_project:
|
206
|
-
rubygems_version: 1.
|
207
|
+
rubygems_version: 1.3.7
|
207
208
|
signing_key:
|
208
209
|
specification_version: 3
|
209
210
|
summary: Provides request based, non-interactive authentication for APIs
|
210
211
|
test_files: []
|
211
|
-
|
212
|
+
|