omniauth-authentiq 0.2.2 → 0.2.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/.gitignore +1 -2
- data/README.md +11 -34
- data/lib/omniauth/authentiq/version.rb +1 -1
- data/lib/omniauth/strategies/authentiq.rb +46 -16
- data/lib/omniauth/strategies/oidc/back_channel_logout_request.rb +103 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d7e7b3e51f99cded0ba659c1161ece4f4f0d0c3
|
4
|
+
data.tar.gz: fb5c1e16c513836280b96a756789d79eeb38c4fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff537913cec88b237d0820091b988dec465f6c981e4a2c52b3fd93ee49c4f707dd5d39c7c489ae258fa0adbc63f7ea6df0a592efac508821f1c57777d203323f
|
7
|
+
data.tar.gz: a7b172b8ff284d0fd07c085e6fcc59e5adfd85dcbbfdb899d6b681508a16fef0bb1575bd22120e3c08dc3051d50f6d205998064d80c9c5ae7d4a5fee6a02fd65
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
# OmniAuth Authentiq
|
2
2
|
|
3
3
|
Official [OmniAuth](https://github.com/omniauth/omniauth/wiki) strategy for authenticating with an Authentiq ID mobile app ([iOS](https://itunes.apple.com/us/app/authentiq-id/id964932341), [Android](https://play.google.com/store/apps/details?id=com.authentiq.authentiqid)).
|
4
|
-
|
4
|
+
|
5
|
+
Application credentials (YOUR_CLIENT_ID and YOUR_CLIENT_SECRET below) can be obtained [at Authentiq](https://www.authentiq.com/register/?utm_source=github&utm_medium=readme&utm_campaign=omniauth).
|
5
6
|
|
6
7
|
## Installation
|
7
8
|
|
8
9
|
Add this line to your application's Gemfile
|
9
10
|
|
10
11
|
```ruby
|
11
|
-
gem 'omniauth-authentiq', '~> 0.2.
|
12
|
+
gem 'omniauth-authentiq', '~> 0.2.3'
|
12
13
|
```
|
13
14
|
|
14
15
|
Then bundle:
|
@@ -20,41 +21,17 @@ Then bundle:
|
|
20
21
|
```ruby
|
21
22
|
use OmniAuth::Builder do
|
22
23
|
provider :authentiq, ENV['AUTHENTIQ_KEY'], ENV['AUTHENTIQ_SECRET'],
|
23
|
-
scope: 'aq:name email~rs aq:push'
|
24
|
-
|
25
|
-
```
|
26
|
-
|
27
|
-
# Scopes
|
28
|
-
|
29
|
-
Authentiq adds the capability to request personal information like name, email, phone number, and address from the Authentiq ID app ([iOS](https://itunes.apple.com/us/app/authentiq-id/id964932341), [Android](https://play.google.com/store/apps/details?id=com.authentiq.authentiqid)).
|
30
|
-
During authentication, and only after the user consents, this information will be shared by the Authentiq ID app.
|
31
|
-
|
32
|
-
Requesting specific information or "scopes" is done by modifying the `scope` parameter in the basic usage example above.
|
33
|
-
Depending on your implementation, you may also need to provide the `redirect_uri` parameter.
|
34
|
-
|
35
|
-
Example:
|
36
|
-
```ruby
|
37
|
-
use OmniAuth::Builder do
|
38
|
-
provider :authentiq, ENV['AUTHENTIQ_KEY'], ENV['AUTHENTIQ_SECRET'],
|
39
|
-
scope: 'aq:name email~rs aq:push phone address',
|
40
|
-
redirect_uri: '<REDIRECT_URI>'
|
24
|
+
scope: 'aq:name email~rs aq:push',
|
25
|
+
enable_remote_sign_out: false
|
41
26
|
end
|
42
27
|
```
|
43
28
|
|
44
|
-
|
45
|
-
- `aq:name` for Name
|
46
|
-
- `email` for Email
|
47
|
-
- `phone` for Phone
|
48
|
-
- `address` for Address
|
49
|
-
- `aq:location` for Location (geo coordinates)
|
50
|
-
- `aq:push` to request permission to sign in via Push Notifications in the Authentiq ID app
|
51
|
-
|
52
|
-
Append `~r` to a scope to explicitly require it from the user.
|
53
|
-
|
54
|
-
Append `~s` to phone or email scope to explicitly require a verified (signed) scope.
|
55
|
-
|
56
|
-
The `~s` and `~r` can be combined to `~rs` to indicate that the scope is both required and should be / have been verified.
|
29
|
+
You can read the wiki for more extensive infomation on how to use the Authentiq Omniauth strategy for your rails application
|
57
30
|
|
31
|
+
* [Homepage](https://github.com/AuthentiqID/omniauth-authentiq/wiki)
|
32
|
+
* [Installation and basic usage](https://github.com/AuthentiqID/omniauth-authentiq/wiki/Installation-and-basic-usage)
|
33
|
+
* [Scopes, redirect uri configuration and response data](https://github.com/AuthentiqID/omniauth-authentiq/wiki/Scopes,-redirect-URI-configuration-and-responses)
|
34
|
+
* [Remote Logout (Backchannel-logout)](https://github.com/AuthentiqID/omniauth-authentiq/wiki/Remote-logout)
|
58
35
|
|
59
36
|
## Tests
|
60
37
|
|
@@ -62,4 +39,4 @@ Tests are coming soon.
|
|
62
39
|
|
63
40
|
## Contributing
|
64
41
|
|
65
|
-
Bug reports and pull requests are welcome
|
42
|
+
Bug reports and pull requests are welcome [here](https://github.com/AuthentiqID/omniauth-authentiq)
|
@@ -3,29 +3,26 @@ require 'omniauth-oauth2'
|
|
3
3
|
module OmniAuth
|
4
4
|
module Strategies
|
5
5
|
class Authentiq < OmniAuth::Strategies::OAuth2
|
6
|
-
|
6
|
+
autoload :BackChannelLogoutRequest, 'omniauth/strategies/oidc/back_channel_logout_request'
|
7
|
+
|
7
8
|
BASE_URL = 'https://connect.authentiq.io/'
|
8
9
|
|
9
|
-
# Authentiq strategy name
|
10
10
|
option :name, 'authentiq'
|
11
11
|
|
12
|
-
# Build the basic client options (url, authorization url, token url)
|
13
12
|
option :client_options, {
|
14
13
|
:site => BASE_URL,
|
15
14
|
:authorize_url => '/authorize',
|
16
15
|
:token_url => '/token'
|
17
16
|
}
|
18
17
|
|
19
|
-
|
20
|
-
option :authorize_options, [:scope, :display]
|
18
|
+
option :authorize_options, [:scope]
|
21
19
|
|
22
20
|
# These are called after authentication has succeeded. If
|
23
21
|
# possible, you should try to set the UID without making
|
24
|
-
# additional calls (if the user id is returned with the
|
25
|
-
# or as a URI parameter). This may not be possible
|
26
|
-
# providers.
|
22
|
+
# additional calls (if the user id is returned with the
|
23
|
+
# token or as a URI parameter). This may not be possible
|
24
|
+
# with all providers.
|
27
25
|
|
28
|
-
# Get the user id from raw info
|
29
26
|
uid { raw_info['sub'] }
|
30
27
|
|
31
28
|
info do
|
@@ -51,18 +48,51 @@ module OmniAuth
|
|
51
48
|
}.reject { |k, v| v.nil? }
|
52
49
|
end
|
53
50
|
|
51
|
+
def request_phase
|
52
|
+
add_openid
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
54
56
|
def raw_info
|
55
|
-
@raw_info ||= access_token.
|
57
|
+
@raw_info ||= decode_idtoken(access_token.params['id_token'])
|
58
|
+
request.update_param('sid', @raw_info['sid'])
|
59
|
+
@raw_info
|
56
60
|
end
|
57
61
|
|
58
|
-
# Over-ride callback_url definition to maintain
|
59
|
-
# compatibility with omniauth-oauth2 >= 1.4.0
|
60
|
-
#
|
61
|
-
# See: https://github.com/intridea/omniauth-oauth2/issues/81
|
62
62
|
def callback_url
|
63
|
-
# Fixes regression in omniauth-oauth2 v1.4.0 by https://github.com/intridea/omniauth-oauth2/commit/85fdbe117c2a4400d001a6368cc359d88f40abc7
|
64
63
|
options[:callback_url] || (full_host + script_name + callback_path)
|
65
64
|
end
|
65
|
+
|
66
|
+
def callback_phase
|
67
|
+
should_sign_out? ? sign_out_phase : super
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_openid
|
71
|
+
unless options.scope.split.include? 'openid'
|
72
|
+
options.scope = options.scope.split.push('openid').join(' ')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def decode_idtoken(idtoken)
|
77
|
+
@jwt_info = JWT.decode idtoken, nil, false
|
78
|
+
@jwt_info[0]
|
79
|
+
end
|
80
|
+
|
81
|
+
def should_sign_out?
|
82
|
+
request.post? && request.params.has_key?('logout_token')
|
83
|
+
end
|
84
|
+
|
85
|
+
def sign_out_phase
|
86
|
+
if options[:enable_remote_sign_out]
|
87
|
+
backchannel_logout_request.new(self, request).call(options)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def backchannel_logout_request
|
94
|
+
BackChannelLogoutRequest
|
95
|
+
end
|
66
96
|
end
|
67
97
|
end
|
68
|
-
end
|
98
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module OmniAuth
|
2
|
+
module Strategies
|
3
|
+
class Authentiq
|
4
|
+
class BackChannelLogoutRequest
|
5
|
+
|
6
|
+
def initialize(strategy, request)
|
7
|
+
@strategy, @request = strategy, request
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(options = {})
|
11
|
+
@options = options
|
12
|
+
|
13
|
+
begin
|
14
|
+
# for sign_out_callback.call(*back_channel_logout_request) to execute
|
15
|
+
# a proc must be set in the devise.rb initializer of the rails app
|
16
|
+
result = sign_out_callback.call(*back_channel_logout_request)
|
17
|
+
rescue StandardError => err
|
18
|
+
result = back_channel_logout_response(400, [err.to_s])
|
19
|
+
else
|
20
|
+
if result
|
21
|
+
result = back_channel_logout_response(200, ['Logout succeeded'])
|
22
|
+
else
|
23
|
+
result = back_channel_logout_response(501, ['Authentiq session does not exist'])
|
24
|
+
end
|
25
|
+
ensure
|
26
|
+
return unless result
|
27
|
+
return result.finish
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def back_channel_logout_request
|
34
|
+
@logout_request || begin
|
35
|
+
decode_logout_token(@request.params['logout_token'])
|
36
|
+
@request
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def decode_logout_token(logout_token)
|
41
|
+
begin
|
42
|
+
logout_jwt = JWT.decode logout_token, @options.client_secret, true, {
|
43
|
+
:algorithm => algorithm,
|
44
|
+
:iss => issuer,
|
45
|
+
:verify_iss => true,
|
46
|
+
:aud => @options.client_id,
|
47
|
+
:verify_aud => true,
|
48
|
+
:verify_iat => true,
|
49
|
+
:verify_jti => true,
|
50
|
+
:verify_sub => true,
|
51
|
+
:leeway => 60
|
52
|
+
}
|
53
|
+
if validate_events(logout_jwt[0]) && validate_nonce(logout_jwt[0]) && validate_sid(logout_jwt[0])
|
54
|
+
@request.update_param('sid', logout_jwt[0]['sid'])
|
55
|
+
else
|
56
|
+
raise 'Logout JWT validation failed. Missing session, events claim or nonce claim is present'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def validate_events(logout_jwt)
|
62
|
+
logout_jwt.key?('events') &&
|
63
|
+
(logout_jwt['events'][0] == 'http://schemas.openid.net/event/backchannel-logout' ||
|
64
|
+
logout_jwt['events'].key?('http://schemas.openid.net/event/backchannel-logout'))
|
65
|
+
end
|
66
|
+
|
67
|
+
def validate_nonce(logout_jwt)
|
68
|
+
!logout_jwt.key?('nonce')
|
69
|
+
end
|
70
|
+
|
71
|
+
def sign_out_callback
|
72
|
+
@options[:enable_remote_sign_out]
|
73
|
+
end
|
74
|
+
|
75
|
+
def validate_sid(logout_jwt)
|
76
|
+
logout_jwt.key?('sid')
|
77
|
+
end
|
78
|
+
|
79
|
+
def back_channel_logout_response(code, body)
|
80
|
+
response = Rack::Response.new
|
81
|
+
response.status = code
|
82
|
+
response['Cache-Control'] = 'no-cache, no-store'
|
83
|
+
response['Pragma'] = 'no-cache'
|
84
|
+
response.headers['Content-Type'] = 'text/plain; charset=utf-8'
|
85
|
+
response.body = body
|
86
|
+
response
|
87
|
+
end
|
88
|
+
|
89
|
+
def issuer
|
90
|
+
@options.issuer.nil? ? 'https://connect.authentiq.io/' : @options.issuer
|
91
|
+
end
|
92
|
+
|
93
|
+
def algorithm
|
94
|
+
if @options.algorithm != nil && (%w(HS256 RS256 ES256).include? @options.client_signed_response_alg)
|
95
|
+
@options.client_signed_response_alg
|
96
|
+
else
|
97
|
+
'HS256'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniauth-authentiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandros Keramidas
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: omniauth-oauth2
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- lib/omniauth/authentiq.rb
|
49
49
|
- lib/omniauth/authentiq/version.rb
|
50
50
|
- lib/omniauth/strategies/authentiq.rb
|
51
|
+
- lib/omniauth/strategies/oidc/back_channel_logout_request.rb
|
51
52
|
- omniauth-authentiq.gemspec
|
52
53
|
homepage: https://github.com/AuthentiqID/omniauth-authentiq
|
53
54
|
licenses:
|