warden-hmac-authentication 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -5
- data/lib/hmac/strategies/base.rb +37 -4
- metadata +22 -22
data/README.md
CHANGED
@@ -83,6 +83,24 @@ or use a Proc that retrieves the secret.
|
|
83
83
|
}
|
84
84
|
end
|
85
85
|
|
86
|
+
### Retrieving the user from the database
|
87
|
+
|
88
|
+
If a callable object is given for the `:retrieve_user` option, this callable will be called after successful authentication. The callable must accept the strategy itself as its only argument. The strategy allows access to all request parameters and header as well as all derived values. The result will be memoized.
|
89
|
+
|
90
|
+
use Warden::Manager do |manager|
|
91
|
+
manager.failure_app = -> env { [401, {"Content-Length" => "0"}, [""]] }
|
92
|
+
# other scopes
|
93
|
+
manager.scope_defaults :hmac, :strategies => [:hmac_query, :hmac_header],
|
94
|
+
:store => false,
|
95
|
+
:hmac => {
|
96
|
+
:retrieve_user => Proc.new {|strategy|
|
97
|
+
User.get(strategy.params["userid"])
|
98
|
+
}
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
An alternative is overwriting the strategies `retrieve_user` method.
|
103
|
+
|
86
104
|
### Controlling the HMAC algorithm
|
87
105
|
|
88
106
|
The algorithm can be controlled using the `:algorithm` option:
|
@@ -120,9 +138,11 @@ No authentication attempt is made if the scheme name in the `Authorization` head
|
|
120
138
|
## Authentication Header Format
|
121
139
|
|
122
140
|
The format of the Authentication Header can be controlled using the `:auth_header_format` directive. The given format string will be interpolated
|
123
|
-
with all given options and the signature. The default value is `%{
|
141
|
+
with all given options and the signature. The default value is `%{scheme} %{signature}` which will result in an auth header with a format such as `HMAC 539263f4f83878a4917d2f9c1521320c28b926a9`. The format string must contain at least the `scheme` and `signature` components.
|
124
142
|
|
125
|
-
The `:auth_header_format` directive has a companion directive, `:auth_header_parse` which
|
143
|
+
The `:auth_header_format` directive has a companion directive, `:auth_header_parse` which must be a regular expression. Any given regular expression will be evaluated against the authorization header. The results can be retrieved using the `parsed_auth_header` method. The regular expression must at least contain a pattern named `scheme` and pattern named `signature`. The default value for this directive is a regular expression that is auto-generated by translating the `:auth_header_format` setting to a regular expression that contains a named capture group for each named part of the format string. Each capture allows for word characters, plus, dash, underscore and dot. The default :auth_header_format `%{scheme} %{signature}` will be translated to `/(?<autschemeh_scheme>[-_+.\w]+) (?<signature>[-_+.\w]+)/`.
|
144
|
+
|
145
|
+
See the section about multiple authentication secrets for a use-case and a comprehensive example.
|
126
146
|
|
127
147
|
## Optional nonce
|
128
148
|
|
@@ -306,9 +326,7 @@ secrets allows us to implement multiple signing keys:
|
|
306
326
|
access_key_id = strategy.parsed_auth_header["access_key_id"]
|
307
327
|
keys[access_key_id]
|
308
328
|
},
|
309
|
-
:auth_header_format => '%{scheme} %{access_key_id} %{signature}'
|
310
|
-
:auth_header_parse => /(?<scheme>\w+) (?<access_key_id>\w+) (?<signature>\w+)/
|
311
|
-
}
|
329
|
+
:auth_header_format => '%{scheme} %{access_key_id} %{signature}' }
|
312
330
|
end
|
313
331
|
|
314
332
|
This combination of settings uses a slightly different Format for the authorization header and transports the secret keys ID in the header of the form `HMAC KEY2 a59456da1f61f86e96622e283780f58b7428c892`
|
data/lib/hmac/strategies/base.rb
CHANGED
@@ -64,11 +64,12 @@ module Warden
|
|
64
64
|
headers
|
65
65
|
end
|
66
66
|
|
67
|
-
# Retrieve a user from the database.
|
67
|
+
# Retrieve a user from the database. Calls the proc given in :retrieve_user, else returns true
|
68
68
|
#
|
69
|
-
# @return [
|
69
|
+
# @return [Mixed] The result of the configured proc, true is no proc was given
|
70
70
|
def retrieve_user
|
71
|
-
true
|
71
|
+
@user ||= config[:retrieve_user].respond_to?(:call) ? config[:retrieve_user].call(self) : true
|
72
|
+
@user
|
72
73
|
end
|
73
74
|
|
74
75
|
# Log a debug message if a logger is available.
|
@@ -119,8 +120,40 @@ module Warden
|
|
119
120
|
(config[:optional_headers] || []) + ["Content-MD5", "Content-Type"]
|
120
121
|
end
|
121
122
|
|
123
|
+
def auth_header_format
|
124
|
+
config[:auth_header_format] || '%{scheme} %{signature}'
|
125
|
+
end
|
126
|
+
|
122
127
|
def auth_header_parse
|
123
|
-
|
128
|
+
unless @auth_header_parse
|
129
|
+
r = config[:auth_header_parse]
|
130
|
+
|
131
|
+
if !r
|
132
|
+
# transforms the auth_header_format to a regular expression
|
133
|
+
# that allows [-_+.\w] for each of the segments in the format string
|
134
|
+
#
|
135
|
+
# '%{scheme} %{signature}' => /(?<scheme>[-_+.\w]+) (?<signature>[-_+.\w]+)/
|
136
|
+
#
|
137
|
+
split_re = /(?<!%)(%{[^}]+})/
|
138
|
+
replace_re = /(?<!%)%{([^}]+)}/
|
139
|
+
|
140
|
+
segments = auth_header_format.split split_re
|
141
|
+
segments.each_index do |i; md, key|
|
142
|
+
md = replace_re.match(segments[i])
|
143
|
+
if ! md.nil?
|
144
|
+
key = md.captures[0].to_sym
|
145
|
+
segments[i] = "(?<#{key}>[-_+.\\w]+)"
|
146
|
+
else
|
147
|
+
segments[i] = segments[i].gsub "%%", "%"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
r = Regexp.new segments.join
|
151
|
+
end
|
152
|
+
|
153
|
+
@auth_header_parse = r
|
154
|
+
end
|
155
|
+
|
156
|
+
@auth_header_parse
|
124
157
|
end
|
125
158
|
|
126
159
|
def lowercase_headers
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: warden-hmac-authentication
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-12-
|
13
|
+
date: 2011-12-14 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: addressable
|
17
|
-
requirement: &
|
17
|
+
requirement: &2155925200 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *2155925200
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: rack
|
28
|
-
requirement: &
|
28
|
+
requirement: &2155924300 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *2155924300
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: trollop
|
39
|
-
requirement: &
|
39
|
+
requirement: &2155923580 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: '0'
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *2155923580
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: warden
|
50
|
-
requirement: &
|
50
|
+
requirement: &2155922780 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: '0'
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *2155922780
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: rake
|
61
|
-
requirement: &
|
61
|
+
requirement: &2155922360 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - ! '>='
|
@@ -66,10 +66,10 @@ dependencies:
|
|
66
66
|
version: '0'
|
67
67
|
type: :development
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *2155922360
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: rack-test
|
72
|
-
requirement: &
|
72
|
+
requirement: &2155921780 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - ! '>='
|
@@ -77,10 +77,10 @@ dependencies:
|
|
77
77
|
version: '0'
|
78
78
|
type: :development
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *2155921780
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: riot
|
83
|
-
requirement: &
|
83
|
+
requirement: &2155921300 !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
85
85
|
requirements:
|
86
86
|
- - ! '>='
|
@@ -88,10 +88,10 @@ dependencies:
|
|
88
88
|
version: '0'
|
89
89
|
type: :development
|
90
90
|
prerelease: false
|
91
|
-
version_requirements: *
|
91
|
+
version_requirements: *2155921300
|
92
92
|
- !ruby/object:Gem::Dependency
|
93
93
|
name: timecop
|
94
|
-
requirement: &
|
94
|
+
requirement: &2155920720 !ruby/object:Gem::Requirement
|
95
95
|
none: false
|
96
96
|
requirements:
|
97
97
|
- - ! '>='
|
@@ -99,10 +99,10 @@ dependencies:
|
|
99
99
|
version: '0'
|
100
100
|
type: :development
|
101
101
|
prerelease: false
|
102
|
-
version_requirements: *
|
102
|
+
version_requirements: *2155920720
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: simplecov
|
105
|
-
requirement: &
|
105
|
+
requirement: &2155920200 !ruby/object:Gem::Requirement
|
106
106
|
none: false
|
107
107
|
requirements:
|
108
108
|
- - ! '>='
|
@@ -110,10 +110,10 @@ dependencies:
|
|
110
110
|
version: '0'
|
111
111
|
type: :development
|
112
112
|
prerelease: false
|
113
|
-
version_requirements: *
|
113
|
+
version_requirements: *2155920200
|
114
114
|
- !ruby/object:Gem::Dependency
|
115
115
|
name: simplecov-html
|
116
|
-
requirement: &
|
116
|
+
requirement: &2155919780 !ruby/object:Gem::Requirement
|
117
117
|
none: false
|
118
118
|
requirements:
|
119
119
|
- - ! '>='
|
@@ -121,7 +121,7 @@ dependencies:
|
|
121
121
|
version: '0'
|
122
122
|
type: :development
|
123
123
|
prerelease: false
|
124
|
-
version_requirements: *
|
124
|
+
version_requirements: *2155919780
|
125
125
|
description: ! "This gem provides request authentication via [HMAC](http://en.wikipedia.org/wiki/Hmac).
|
126
126
|
The main usage is request based, noninteractive\n authentication for API implementations.
|
127
127
|
Two strategies are supported that differ mainly in how the authentication information
|