rack-u2f 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|