rack-u2f 0.1.2 → 0.1.3
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.
- checksums.yaml +4 -4
- data/README.md +32 -1
- data/lib/rack/u2f/registration_server.rb +22 -18
- data/lib/rack/u2f/registration_store.rb +14 -13
- data/lib/rack/u2f/registration_store/active_record_store.rb +10 -0
- data/lib/rack/u2f/version.rb +1 -1
- data/rack-u2f.gemspec +2 -0
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fadfe6cc870a2dbed3a6fcde4be9f7cb309ca2d0
|
4
|
+
data.tar.gz: 562f528d75d8eeccc0901eed6367cb9bac0723e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 712654a48a465300d0af1a9f81456077e8f78f6f0b207c4691a37d27b09350490b353b517b7081f9ca8bd75bac5b0d9514910d25741adab6d24c6730573f8e8b
|
7
|
+
data.tar.gz: 2dabffb61eb6ba305a610166f47a432364f5d60ddbd1215c656a2f3a8f57905967df08ca23145d513992a7b1c448be73b7a00f66f93f9b1113d1c41ce3b48bbe
|
data/README.md
CHANGED
@@ -25,7 +25,7 @@ And then execute:
|
|
25
25
|
|
26
26
|
Rack U2F has two components; A Rack app to register U2F devices and Rack Middleware to authenticate against registered U2F devices. When registration is enabled, you can add a u2f device through the `u2f_register_path`.
|
27
27
|
|
28
|
-
For U2F to work, persistence of a counter is required, therefore a storage mechanism is needed. Right now, this gem supports [Redis](https://redis.io),
|
28
|
+
For U2F to work, persistence of a counter is required, therefore a storage mechanism is needed. Right now, this gem supports [Redis](https://redis.io), and ActiveRecord. There is a simple API to add more stores as required.
|
29
29
|
|
30
30
|
## Config
|
31
31
|
|
@@ -43,6 +43,10 @@ config.middleware.use Rack::U2f::AuthenticationMiddleware, {
|
|
43
43
|
}
|
44
44
|
```
|
45
45
|
|
46
|
+
## Store Config
|
47
|
+
|
48
|
+
### Redis Store
|
49
|
+
|
46
50
|
The `Rack::U2f::RegistrationStore::RedisStore.new` by default uses `Redis.new` as the redis connection.
|
47
51
|
You can pass in your own connection as the single argument to `RedisStore.new()`, for example:
|
48
52
|
|
@@ -50,11 +54,35 @@ You can pass in your own connection as the single argument to `RedisStore.new()`
|
|
50
54
|
store: Rack::U2f::RegistrationStore::RedisStore.new(Redis.new(url: 'redis://10.1.1.1/'))
|
51
55
|
```
|
52
56
|
|
57
|
+
### ActiveRecord Store
|
58
|
+
|
59
|
+
Use `Rack::U2f::RegistrationStore::ActiveRecordStore.new(ArModel)`. The `ArModel` should be an active record model with the following schema;
|
60
|
+
|
61
|
+
```
|
62
|
+
t.string :key_handle, index: true
|
63
|
+
t.text :certificate
|
64
|
+
t.text :public_key
|
65
|
+
t.integer :counter
|
66
|
+
```
|
67
|
+
|
68
|
+
## Other Config
|
69
|
+
|
70
|
+
### enable_registration
|
71
|
+
|
53
72
|
If `enable_registration` is true then you will be able to visit `/_u2f_register` to register a new key.
|
54
73
|
Registration should not be enabled in production. It is possible to mount the registration server separately as it is a rack app.
|
55
74
|
|
56
75
|
When authenticated, the session is for further authentication. *You must be using a secure session store*.
|
57
76
|
|
77
|
+
### after_sign_in_url
|
78
|
+
|
79
|
+
The url to be directed to after successful sign in, default: `"/"`
|
80
|
+
|
81
|
+
### exclude_urls
|
82
|
+
|
83
|
+
An array of regular expressions to match on the path to exclude urls from the u2f requirement.
|
84
|
+
Be careful here; generally prefixes is the safest way `%r{\A/myprefix}`. Keep in mind that people can add things to paths that may cause an otherwise excluded url to match.
|
85
|
+
|
58
86
|
## Development
|
59
87
|
|
60
88
|
There is a demo app in the DemoApp folder. Integration tests will require a fake/software u2f key, and is on the TODO list.
|
@@ -70,3 +98,6 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/eadz/r
|
|
70
98
|
## License
|
71
99
|
|
72
100
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
101
|
+
|
102
|
+
## Todo ( contributions welcome )
|
103
|
+
Integration tests using a fake token such as the [soft token helper from google]( https://github.com/google/u2f-ref-code/blob/master/u2f-chrome-extension/softtokenhelper.js)
|
@@ -10,37 +10,41 @@ module Rack
|
|
10
10
|
def initialize(config)
|
11
11
|
@config = config
|
12
12
|
@store = config[:store]
|
13
|
+
@registration_enabled = config[:enable_registration]
|
13
14
|
raise 'Missing RegistrationMiddleware Config' if @config.nil?
|
14
15
|
end
|
15
16
|
|
16
17
|
def call(env)
|
17
|
-
return
|
18
|
+
return registration_disabled unless @registration_enabled
|
18
19
|
request = Rack::Request.new(env)
|
19
20
|
if request.get?
|
20
21
|
generate_registration(request)
|
21
22
|
else
|
22
|
-
|
23
|
-
|
24
|
-
response = U2F::RegisterResponse.load_from_json(request.params['response'])
|
25
|
-
reg = begin
|
26
|
-
u2f.register!(request.session['challenges'], response)
|
27
|
-
rescue U2F::Error => e
|
28
|
-
return [422, {}, ['Unable to register device']]
|
29
|
-
ensure
|
30
|
-
request.session.delete('challenges')
|
31
|
-
end
|
32
|
-
@store.store_registration(
|
33
|
-
certificate: reg.certificate,
|
34
|
-
key_handle: reg.key_handle,
|
35
|
-
public_key: reg.public_key,
|
36
|
-
counter: reg.counter
|
37
|
-
)
|
38
|
-
return [200, {}, ["Registration Successful"]]
|
23
|
+
store_registration(request)
|
39
24
|
end
|
40
25
|
end
|
41
26
|
|
42
27
|
private
|
43
28
|
|
29
|
+
def registration_disabled
|
30
|
+
Rack::Response.new('Registration Disabled', 403)
|
31
|
+
end
|
32
|
+
|
33
|
+
def store_registration(request)
|
34
|
+
u2f = U2F::U2F.new(extract_app_id(request))
|
35
|
+
response = U2F::RegisterResponse.load_from_json(request.params['response'])
|
36
|
+
u2f.register!(request.session['challenges'], response)
|
37
|
+
@store.store_registration(
|
38
|
+
certificate: reg.certificate, key_handle: reg.key_handle,
|
39
|
+
public_key: reg.public_key, counter: reg.counter
|
40
|
+
)
|
41
|
+
Rack::Response.new('Registration Successful')
|
42
|
+
rescue U2F::Error
|
43
|
+
return Rack::Response.new('Unable to register device', 422)
|
44
|
+
ensure
|
45
|
+
request.session.delete('challenges')
|
46
|
+
end
|
47
|
+
|
44
48
|
def generate_registration(request)
|
45
49
|
u2f = U2F::U2F.new('https://junk.ngrok.io')
|
46
50
|
registration_requests = u2f.registration_requests
|
@@ -1,22 +1,23 @@
|
|
1
|
+
require 'rack/u2f/registration_store/active_record_store'
|
1
2
|
require 'rack/u2f/registration_store/redis_store'
|
2
3
|
|
3
4
|
module Rack
|
4
5
|
module U2f
|
5
6
|
# Store to keep track of tokens
|
6
7
|
module RegistrationStore
|
7
|
-
class AbstractStore
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
8
|
+
# class AbstractStore
|
9
|
+
# def initialize(*args)
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def store_registration(certificate:, key_handle:, public_key:, counter:)
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# def update_registration(key_handle:, counter:)
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# def key_handles
|
19
|
+
# end
|
20
|
+
# end
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
@@ -8,15 +8,25 @@ module Rack
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def store_registration(certificate:, key_handle:, public_key:, counter:)
|
11
|
+
@model.create!(
|
12
|
+
certificate: certificate,
|
13
|
+
key_handle: key_handle,
|
14
|
+
public_key: public_key,
|
15
|
+
counter: counter
|
16
|
+
)
|
11
17
|
end
|
12
18
|
|
13
19
|
def get_registration(key_handle:)
|
20
|
+
key = @model.where(key_handle: key_handle).first
|
21
|
+
key && key.as_json.slice('certificate', 'public_key', 'counter')
|
14
22
|
end
|
15
23
|
|
16
24
|
def update_registration(key_handle:, counter:)
|
25
|
+
@model.where(key_handle: key_handle).update_all(counter: counter)
|
17
26
|
end
|
18
27
|
|
19
28
|
def key_handles
|
29
|
+
@model.pluck(:key_handle)
|
20
30
|
end
|
21
31
|
end
|
22
32
|
end
|
data/lib/rack/u2f/version.rb
CHANGED
data/rack-u2f.gemspec
CHANGED
@@ -26,9 +26,11 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_dependency 'rack', '~> 2.0'
|
27
27
|
spec.add_dependency 'u2f', '~> 1.0'
|
28
28
|
|
29
|
+
spec.add_development_dependency 'activerecord', '>= 4.0'
|
29
30
|
spec.add_development_dependency 'bundler', '~> 1.15'
|
30
31
|
spec.add_development_dependency 'fakeredis', '~> 0.6.0'
|
31
32
|
spec.add_development_dependency 'rake', '~> 10.0'
|
32
33
|
spec.add_development_dependency 'redis', '~> 3.2'
|
33
34
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
35
|
+
spec.add_development_dependency 'sqlite3', '~> 1.3'
|
34
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-u2f
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eaden McKee
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mustache
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activerecord
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: bundler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +136,20 @@ dependencies:
|
|
122
136
|
- - "~>"
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '3.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: sqlite3
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '1.3'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '1.3'
|
125
153
|
description: rack middleware to add u2f authentication to a rack app. Includes registration.
|
126
154
|
email:
|
127
155
|
- mail@eaden.net
|