omniauth-auth0 2.5.0 → 2.6.0
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/CHANGELOG.md +8 -0
- data/README.md +69 -0
- data/lib/omniauth-auth0/version.rb +1 -1
- data/lib/omniauth/auth0/jwt_validator.rb +13 -0
- data/lib/omniauth/strategies/auth0.rb +1 -1
- data/spec/omniauth/auth0/jwt_validator_spec.rb +35 -0
- data/spec/omniauth/strategies/auth0_spec.rb +50 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f45e6ee50254603367c7de482ce5537b48c5faf1bc7a4f2797cf461f21b37198
|
4
|
+
data.tar.gz: 88eb699d3cf59148df15728b42d517e010bebe29617f1f9e972dc9656e5a79a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 829fd68186ab4685d7628b6a7c3a0cce95b1008396e6b6588e72b30ff7b077c103109bafe8e3e480539a07d715550fed27b2d73f537e505498a8b434655a0776
|
7
|
+
data.tar.gz: 8d03a181ad81f1b08618f542d1971d298a9751ca5d02e949bcf8f60bbf4d6ba2ce3463e6f5ce5a01945a82f24ce7e6f67881192f3e4214a2d05bb556ba6ef66e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [v2.6.0](https://github.com/auth0/omniauth-auth0/tree/v2.6.0) (2021-04-01)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/auth0/omniauth-auth0/compare/v2.5.0...v2.6.0)
|
6
|
+
|
7
|
+
**Added**
|
8
|
+
- Org Support [SDK-2395] [\#124](https://github.com/auth0/omniauth-auth0/pull/124) ([davidpatrick](https://github.com/davidpatrick))
|
9
|
+
- Add login_hint to permitted params [\#123](https://github.com/auth0/omniauth-auth0/pull/123) ([Roriz](https://github.com/Roriz))
|
10
|
+
|
3
11
|
## [v2.5.0](https://github.com/auth0/omniauth-auth0/tree/v2.5.0) (2021-01-21)
|
4
12
|
|
5
13
|
[Full Changelog](https://github.com/auth0/omniauth-auth0/compare/v2.4.2...v2.5.0)
|
data/README.md
CHANGED
@@ -131,9 +131,78 @@ In some scenarios, you may need to pass specific query parameters to `/authorize
|
|
131
131
|
- `connection_scope`
|
132
132
|
- `prompt`
|
133
133
|
- `screen_hint` (only relevant to New Universal Login Experience)
|
134
|
+
- `organization`
|
135
|
+
- `invitation`
|
134
136
|
|
135
137
|
Simply pass these query parameters to your OmniAuth redirect endpoint to enable their behavior.
|
136
138
|
|
139
|
+
## Examples
|
140
|
+
|
141
|
+
### Auth0 Organizations (Closed Beta)
|
142
|
+
|
143
|
+
Organizations is a set of features that provide better support for developers who build and maintain SaaS and Business-to-Business (B2B) applications.
|
144
|
+
|
145
|
+
Using Organizations, you can:
|
146
|
+
|
147
|
+
- Represent teams, business customers, partner companies, or any logical grouping of users that should have different ways of accessing your applications, as organizations.
|
148
|
+
- Manage their membership in a variety of ways, including user invitation.
|
149
|
+
- Configure branded, federated login flows for each organization.
|
150
|
+
- Implement role-based access control, such that users can have different roles when authenticating in the context of different organizations.
|
151
|
+
- Build administration capabilities into your products, using Organizations APIs, so that those businesses can manage their own organizations.
|
152
|
+
|
153
|
+
Note that Organizations is currently only available to customers on our Enterprise and Startup subscription plans.
|
154
|
+
|
155
|
+
#### Logging in with an Organization
|
156
|
+
|
157
|
+
Logging in with an Organization is as easy as passing the parameters to the authorize endpoint. You can do this with
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
<%=
|
161
|
+
button_to 'Login', 'auth/auth0',
|
162
|
+
method: :post,
|
163
|
+
params: {
|
164
|
+
# Found in your Auth0 dashboard, under Organization settings:
|
165
|
+
organization: '{AUTH0_ORGANIZATION}'
|
166
|
+
}
|
167
|
+
%>
|
168
|
+
```
|
169
|
+
|
170
|
+
Alternatively you can configure the organization when you register the provider:
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
provider
|
174
|
+
:auth0,
|
175
|
+
ENV['AUTH0_CLIENT_ID'],
|
176
|
+
ENV['AUTH0_CLIENT_SECRET'],
|
177
|
+
ENV['AUTH0_DOMAIN'],
|
178
|
+
{
|
179
|
+
authorize_params: {
|
180
|
+
scope: 'openid read:users',
|
181
|
+
audience: 'https://{AUTH0_DOMAIN}/api',
|
182
|
+
organization: '{AUTH0_ORGANIZATION}'
|
183
|
+
}
|
184
|
+
}
|
185
|
+
```
|
186
|
+
|
187
|
+
#### Accepting user invitations
|
188
|
+
|
189
|
+
Auth0 Organizations allow users to be invited using emailed links, which will direct a user back to your application. The URL the user will arrive at is based on your configured `Application Login URI`, which you can change from your Application's settings inside the Auth0 dashboard.
|
190
|
+
|
191
|
+
When the user arrives at your application using an invite link, you can expect three query parameters to be provided: `invitation`, `organization`, and `organization_name`. These will always be delivered using a GET request.
|
192
|
+
|
193
|
+
You can then supply those parametrs to a `button_to` or `link_to` helper
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
<%=
|
197
|
+
button_to 'Login', 'auth/auth0',
|
198
|
+
method: :post,
|
199
|
+
params: {
|
200
|
+
organization: '{YOUR_ORGANIZATION_ID}',
|
201
|
+
invitation: '{INVITE_CODE}'
|
202
|
+
}
|
203
|
+
%>
|
204
|
+
```
|
205
|
+
|
137
206
|
## Contribution
|
138
207
|
|
139
208
|
We appreciate feedback and contribution to this repo! Before you get started, please see the following:
|
@@ -174,6 +174,7 @@ module OmniAuth
|
|
174
174
|
leeway = authorize_params[:leeway] || 60
|
175
175
|
max_age = authorize_params[:max_age]
|
176
176
|
nonce = authorize_params[:nonce]
|
177
|
+
organization = authorize_params[:organization]
|
177
178
|
|
178
179
|
verify_iss(id_token)
|
179
180
|
verify_sub(id_token)
|
@@ -183,6 +184,7 @@ module OmniAuth
|
|
183
184
|
verify_nonce(id_token, nonce)
|
184
185
|
verify_azp(id_token)
|
185
186
|
verify_auth_time(id_token, leeway, max_age)
|
187
|
+
verify_org(id_token, organization)
|
186
188
|
end
|
187
189
|
|
188
190
|
def verify_iss(id_token)
|
@@ -260,6 +262,17 @@ module OmniAuth
|
|
260
262
|
end
|
261
263
|
end
|
262
264
|
end
|
265
|
+
|
266
|
+
def verify_org(id_token, organization)
|
267
|
+
if organization
|
268
|
+
org_id = id_token['org_id']
|
269
|
+
if !org_id || !org_id.is_a?(String)
|
270
|
+
raise OmniAuth::Auth0::TokenValidationError.new("Organization Id (org_id) claim must be a string present in the ID token")
|
271
|
+
elsif org_id != organization
|
272
|
+
raise OmniAuth::Auth0::TokenValidationError.new("Organization Id (org_id) claim value mismatch in the ID token; expected '#{organization}', found '#{org_id}'")
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
263
276
|
end
|
264
277
|
end
|
265
278
|
end
|
@@ -84,7 +84,7 @@ module OmniAuth
|
|
84
84
|
# Define the parameters used for the /authorize endpoint
|
85
85
|
def authorize_params
|
86
86
|
params = super
|
87
|
-
%w[connection connection_scope prompt screen_hint].each do |key|
|
87
|
+
%w[connection connection_scope prompt screen_hint login_hint organization invitation].each do |key|
|
88
88
|
params[key] = request.params[key] if request.params.key?(key)
|
89
89
|
end
|
90
90
|
|
@@ -476,6 +476,41 @@ describe OmniAuth::Auth0::JWTValidator do
|
|
476
476
|
expect(id_token['auth_time']).to eq(auth_time)
|
477
477
|
end
|
478
478
|
|
479
|
+
it 'should fail when authorize params has organization but org_id is missing in the token', focus: true do
|
480
|
+
payload = {
|
481
|
+
iss: "https://#{domain}/",
|
482
|
+
sub: 'sub',
|
483
|
+
aud: client_id,
|
484
|
+
exp: future_timecode,
|
485
|
+
iat: past_timecode
|
486
|
+
}
|
487
|
+
|
488
|
+
token = make_hs256_token(payload)
|
489
|
+
expect do
|
490
|
+
jwt_validator.verify(token, { organization: 'Test Org' })
|
491
|
+
end.to raise_error(an_instance_of(OmniAuth::Auth0::TokenValidationError).and having_attributes({
|
492
|
+
message: "Organization Id (org_id) claim must be a string present in the ID token"
|
493
|
+
}))
|
494
|
+
end
|
495
|
+
|
496
|
+
it 'should fail when authorize params has organization but token org_id does not match', focus: true do
|
497
|
+
payload = {
|
498
|
+
iss: "https://#{domain}/",
|
499
|
+
sub: 'sub',
|
500
|
+
aud: client_id,
|
501
|
+
exp: future_timecode,
|
502
|
+
iat: past_timecode,
|
503
|
+
org_id: 'Wrong Org'
|
504
|
+
}
|
505
|
+
|
506
|
+
token = make_hs256_token(payload)
|
507
|
+
expect do
|
508
|
+
jwt_validator.verify(token, { organization: 'Test Org' })
|
509
|
+
end.to raise_error(an_instance_of(OmniAuth::Auth0::TokenValidationError).and having_attributes({
|
510
|
+
message: "Organization Id (org_id) claim value mismatch in the ID token; expected 'Test Org', found 'Wrong Org'"
|
511
|
+
}))
|
512
|
+
end
|
513
|
+
|
479
514
|
it 'should fail for RS256 token when kid is incorrect' do
|
480
515
|
domain = 'example.org'
|
481
516
|
sub = 'abc123'
|
@@ -91,6 +91,9 @@ describe OmniAuth::Strategies::Auth0 do
|
|
91
91
|
expect(redirect_url).not_to have_query('connection_scope')
|
92
92
|
expect(redirect_url).not_to have_query('prompt')
|
93
93
|
expect(redirect_url).not_to have_query('screen_hint')
|
94
|
+
expect(redirect_url).not_to have_query('login_hint')
|
95
|
+
expect(redirect_url).not_to have_query('organization')
|
96
|
+
expect(redirect_url).not_to have_query('invitation')
|
94
97
|
end
|
95
98
|
|
96
99
|
it 'redirects to hosted login page' do
|
@@ -107,6 +110,9 @@ describe OmniAuth::Strategies::Auth0 do
|
|
107
110
|
expect(redirect_url).not_to have_query('connection_scope')
|
108
111
|
expect(redirect_url).not_to have_query('prompt')
|
109
112
|
expect(redirect_url).not_to have_query('screen_hint')
|
113
|
+
expect(redirect_url).not_to have_query('login_hint')
|
114
|
+
expect(redirect_url).not_to have_query('organization')
|
115
|
+
expect(redirect_url).not_to have_query('invitation')
|
110
116
|
end
|
111
117
|
|
112
118
|
it 'redirects to the hosted login page with connection_scope' do
|
@@ -130,6 +136,9 @@ describe OmniAuth::Strategies::Auth0 do
|
|
130
136
|
expect(redirect_url).to have_query('prompt', 'login')
|
131
137
|
expect(redirect_url).not_to have_query('auth0Client')
|
132
138
|
expect(redirect_url).not_to have_query('connection')
|
139
|
+
expect(redirect_url).not_to have_query('login_hint')
|
140
|
+
expect(redirect_url).not_to have_query('organization')
|
141
|
+
expect(redirect_url).not_to have_query('invitation')
|
133
142
|
end
|
134
143
|
|
135
144
|
it 'redirects to hosted login page with screen_hint=signup' do
|
@@ -144,6 +153,47 @@ describe OmniAuth::Strategies::Auth0 do
|
|
144
153
|
expect(redirect_url).to have_query('screen_hint', 'signup')
|
145
154
|
expect(redirect_url).not_to have_query('auth0Client')
|
146
155
|
expect(redirect_url).not_to have_query('connection')
|
156
|
+
expect(redirect_url).not_to have_query('login_hint')
|
157
|
+
expect(redirect_url).not_to have_query('organization')
|
158
|
+
expect(redirect_url).not_to have_query('invitation')
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'redirects to hosted login page with organization=TestOrg and invitation=TestInvite' do
|
162
|
+
get 'auth/auth0?organization=TestOrg&invitation=TestInvite'
|
163
|
+
expect(last_response.status).to eq(302)
|
164
|
+
redirect_url = last_response.headers['Location']
|
165
|
+
expect(redirect_url).to start_with('https://samples.auth0.com/authorize')
|
166
|
+
expect(redirect_url).to have_query('response_type', 'code')
|
167
|
+
expect(redirect_url).to have_query('state')
|
168
|
+
expect(redirect_url).to have_query('client_id')
|
169
|
+
expect(redirect_url).to have_query('redirect_uri')
|
170
|
+
expect(redirect_url).to have_query('organization', 'TestOrg')
|
171
|
+
expect(redirect_url).to have_query('invitation', 'TestInvite')
|
172
|
+
expect(redirect_url).not_to have_query('auth0Client')
|
173
|
+
expect(redirect_url).not_to have_query('connection')
|
174
|
+
expect(redirect_url).not_to have_query('connection_scope')
|
175
|
+
expect(redirect_url).not_to have_query('prompt')
|
176
|
+
expect(redirect_url).not_to have_query('screen_hint')
|
177
|
+
expect(redirect_url).not_to have_query('login_hint')
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'redirects to hosted login page with login_hint=example@mail.com' do
|
181
|
+
get 'auth/auth0?login_hint=example@mail.com'
|
182
|
+
expect(last_response.status).to eq(302)
|
183
|
+
redirect_url = last_response.headers['Location']
|
184
|
+
expect(redirect_url).to start_with('https://samples.auth0.com/authorize')
|
185
|
+
expect(redirect_url).to have_query('response_type', 'code')
|
186
|
+
expect(redirect_url).to have_query('state')
|
187
|
+
expect(redirect_url).to have_query('client_id')
|
188
|
+
expect(redirect_url).to have_query('redirect_uri')
|
189
|
+
expect(redirect_url).to have_query('login_hint', 'example@mail.com')
|
190
|
+
expect(redirect_url).not_to have_query('auth0Client')
|
191
|
+
expect(redirect_url).not_to have_query('connection')
|
192
|
+
expect(redirect_url).not_to have_query('connection_scope')
|
193
|
+
expect(redirect_url).not_to have_query('prompt')
|
194
|
+
expect(redirect_url).not_to have_query('screen_hint')
|
195
|
+
expect(redirect_url).not_to have_query('organization')
|
196
|
+
expect(redirect_url).not_to have_query('invitation')
|
147
197
|
end
|
148
198
|
|
149
199
|
describe 'callback' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniauth-auth0
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Auth0
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01
|
11
|
+
date: 2021-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: omniauth
|
@@ -118,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
118
|
- !ruby/object:Gem::Version
|
119
119
|
version: '0'
|
120
120
|
requirements: []
|
121
|
-
rubygems_version: 3.
|
121
|
+
rubygems_version: 3.1.2
|
122
122
|
signing_key:
|
123
123
|
specification_version: 4
|
124
124
|
summary: OmniAuth OAuth2 strategy for the Auth0 platform.
|