nginx_omniauth_adapter 0.2.0 → 1.0.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/Gemfile +2 -0
- data/README.md +10 -1
- data/circle.yml +35 -0
- data/example/nginx-site.conf +1 -0
- data/example/nginx.conf +3 -0
- data/lib/nginx_omniauth_adapter/app.rb +52 -5
- data/lib/nginx_omniauth_adapter/version.rb +1 -1
- 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: a96ef0739bfef47af1b4a8fb09debc9c19993268
|
4
|
+
data.tar.gz: 44aabb34e2c339f88e49db0bee0d4e192b150466
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 261454c8ab6c76b725ea4eae8e14f4db6166c5d13e5aefa5f8208014c07c960b970eb941b2a916de39da700e314fedacaf17bd9ff9e13f9e4d4e722eb81be046
|
7
|
+
data.tar.gz: 02419d04c5c6a591088fe8c79834d5571bf341e47b91f9d993626b0a5e05b03f3d2349dcd5a2ae661b5758fac43d38c159904d342e204859c4306a21ec8cc7ae
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# NginxOmniauthAdapter - Use omniauth for nginx `auth_request`
|
2
2
|
|
3
|
+
[](https://circleci.com/gh/sorah/nginx_omniauth_adapter)
|
4
|
+
|
3
5
|
Use [omniauth](https://github.com/intridea/omniauth) for your nginx's authentication via ngx_http_auth_request_module.
|
4
6
|
|
5
7
|
NginxOmniauthAdapter provides small Rack app (built with Sinatra) for `auth_request`.
|
@@ -40,7 +42,12 @@ Then write `config.ru` then deploy it. (see ./config.ru for example)
|
|
40
42
|
|
41
43
|
### Using docker
|
42
44
|
|
43
|
-
|
45
|
+
- Prebuilt: https://quay.io/repository/sorah/nginx_omniauth_adapter
|
46
|
+
- Own your risk.
|
47
|
+
- They're built at circleci
|
48
|
+
- Build manually: checkout this repo and run `docker build .`.
|
49
|
+
- Much safer.
|
50
|
+
- But if you can't trust upstream image `quay.io/sorah/rbenv:2.2`, write your own Dockerfile. This is just a simple Rack app.
|
44
51
|
|
45
52
|
## Configuration
|
46
53
|
|
@@ -94,6 +101,8 @@ run NginxOmniauthAdapter.app(
|
|
94
101
|
|
95
102
|
## How it works
|
96
103
|
|
104
|
+

|
105
|
+
|
97
106
|
1. _browser_ access to restricted area (where `auth_request` has enabled)
|
98
107
|
2. _nginx_ sends subrequest to `/_auth/challenge`. It will be proxied to _adapter app_ (`GET /test`)
|
99
108
|
3. _adapter app_ `/test` returns 401 when _request (browser)_ doesn't have valid cookie
|
data/circle.yml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
machine:
|
2
|
+
services:
|
3
|
+
- docker
|
4
|
+
ruby:
|
5
|
+
version: 2.2.3
|
6
|
+
|
7
|
+
dependencies:
|
8
|
+
cache_directories:
|
9
|
+
- bin
|
10
|
+
- ~/docker
|
11
|
+
pre:
|
12
|
+
- sudo apt-get install nginx
|
13
|
+
- if [ ! -d bin ]; then mkdir bin; fi
|
14
|
+
- if [ ! -x bin/git-set-mtime ]; then curl -o bin/git-set-mtime https://drone.io/github.com/rosylilly/git-set-mtime/files/artifacts/bin/linux_amd64/git-set-mtime && chmod +x bin/git-set-mtime; fi
|
15
|
+
- docker login -u "${DOCKER_USER}" -p "${DOCKER_PASSWORD}" -e "${DOCKER_EMAIL}" https://quay.io
|
16
|
+
- bin/git-set-mtime
|
17
|
+
- mkdir -p ~/docker
|
18
|
+
- if [[ -e ~/docker/cache.tar ]]; then docker load -i ~/docker/cache.tar; fi
|
19
|
+
- docker pull quay.io/sorah/rbenv:2.2
|
20
|
+
- BASE_ID="$(docker inspect -f '{{.Id}}' quay.io/sorah/rbenv:2.2)"; if [[ "_${BASE_ID}" != "_$(cat ~/docker/cache.id)" ]]; then docker save quay.io/sorah/rbenv:2.2 > ~/docker/cache.tar && echo "${BASE_ID}" > ~/docker/cache.id; fi
|
21
|
+
- docker pull quay.io/sorah/nginx_omniauth_adapter:latest
|
22
|
+
- docker build -t quay.io/sorah/nginx_omniauth_adapter:${CIRCLE_SHA1} .
|
23
|
+
|
24
|
+
test:
|
25
|
+
override:
|
26
|
+
- bundle exec env ADAPTER_DOCKER=quay.io/sorah/nginx_omniauth_adapter:${CIRCLE_SHA1} rspec spec/integration_spec.rb
|
27
|
+
- "echo '==== LOG ====' && cat /tmp/nginx_omniauth_helper.spec.log"
|
28
|
+
|
29
|
+
deployment:
|
30
|
+
production:
|
31
|
+
branch: master
|
32
|
+
commands:
|
33
|
+
- docker tag -f quay.io/sorah/nginx_omniauth_adapter:${CIRCLE_SHA1} quay.io/sorah/nginx_omniauth_adapter:latest
|
34
|
+
- docker push quay.io/sorah/nginx_omniauth_adapter:${CIRCLE_SHA1}
|
35
|
+
- docker push quay.io/sorah/nginx_omniauth_adapter:latest
|
data/example/nginx-site.conf
CHANGED
data/example/nginx.conf
CHANGED
@@ -3,6 +3,7 @@ require 'uri'
|
|
3
3
|
require 'time'
|
4
4
|
require 'openssl'
|
5
5
|
require 'json'
|
6
|
+
require 'securerandom'
|
6
7
|
|
7
8
|
module NginxOmniauthAdapter
|
8
9
|
class App < Sinatra::Base
|
@@ -60,13 +61,30 @@ module NginxOmniauthAdapter
|
|
60
61
|
adapter_config[:policy_proc] || proc { true }
|
61
62
|
end
|
62
63
|
|
64
|
+
def log(h={})
|
65
|
+
h = {
|
66
|
+
time: Time.now.xmlschema,
|
67
|
+
severity: :info,
|
68
|
+
logged_in: (!!current_user).inspect,
|
69
|
+
provider: current_user && current_user[:provider],
|
70
|
+
uid: current_user && current_user[:uid],
|
71
|
+
flow_id: current_flow_id,
|
72
|
+
}.merge(h)
|
73
|
+
|
74
|
+
str = h.map { |*kv| kv.join(?:) }.join(?\t)
|
75
|
+
|
76
|
+
puts str
|
77
|
+
if h[:severity] == :warning || h[:severity] == :error
|
78
|
+
$stderr.puts str
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
63
82
|
def default_back_to
|
64
83
|
# TODO:
|
65
84
|
'/'
|
66
85
|
end
|
67
86
|
|
68
87
|
def sanitized_back_to_param
|
69
|
-
p params[:back_to]
|
70
88
|
if allowed_back_to_url === params[:back_to]
|
71
89
|
params[:back_to]
|
72
90
|
else
|
@@ -75,7 +93,6 @@ module NginxOmniauthAdapter
|
|
75
93
|
end
|
76
94
|
|
77
95
|
def sanitized_app_callback_param
|
78
|
-
p params[:callback]
|
79
96
|
if allowed_app_callback_url === params[:callback]
|
80
97
|
params[:callback]
|
81
98
|
else
|
@@ -83,6 +100,14 @@ module NginxOmniauthAdapter
|
|
83
100
|
end
|
84
101
|
end
|
85
102
|
|
103
|
+
def set_flow_id!
|
104
|
+
session[:flow_id] = SecureRandom.uuid
|
105
|
+
end
|
106
|
+
|
107
|
+
def current_flow_id
|
108
|
+
session[:flow_id]
|
109
|
+
end
|
110
|
+
|
86
111
|
def current_user
|
87
112
|
session[:user]
|
88
113
|
end
|
@@ -117,6 +142,7 @@ module NginxOmniauthAdapter
|
|
117
142
|
|
118
143
|
def update_session!(auth = nil)
|
119
144
|
unless session[:app_callback]
|
145
|
+
log severity: :error, message: 'missing app_callback'
|
120
146
|
raise '[BUG] app_callback is missing'
|
121
147
|
end
|
122
148
|
|
@@ -148,7 +174,12 @@ module NginxOmniauthAdapter
|
|
148
174
|
session.merge!(adapter_session)
|
149
175
|
|
150
176
|
session_param = encrypt_session_param(app_session)
|
177
|
+
|
178
|
+
log(message: 'update_session', app_callback: session[:app_callback])
|
179
|
+
|
151
180
|
redirect "#{session.delete(:app_callback)}?session=#{session_param}"
|
181
|
+
ensure
|
182
|
+
session[:flow_id] = nil
|
152
183
|
end
|
153
184
|
|
154
185
|
def secret_key
|
@@ -212,10 +243,12 @@ module NginxOmniauthAdapter
|
|
212
243
|
|
213
244
|
get '/test' do
|
214
245
|
unless current_user
|
246
|
+
log(message: 'test_not_logged_in', original_uri: request.env['HTTP_X_NGX_OMNIAUTH_ORIGINAL_URI'])
|
215
247
|
halt 401
|
216
248
|
end
|
217
249
|
|
218
250
|
if app_authorization_expired?
|
251
|
+
log(message: 'test_app_authorization_expired', original_uri: request.env['HTTP_X_NGX_OMNIAUTH_ORIGINAL_URI'])
|
219
252
|
halt 401
|
220
253
|
end
|
221
254
|
|
@@ -238,34 +271,47 @@ module NginxOmniauthAdapter
|
|
238
271
|
callback = URI.encode_www_form_component(request.env['HTTP_X_NGX_OMNIAUTH_INITIATE_CALLBACK'])
|
239
272
|
|
240
273
|
if back_to == '' || callback == '' || back_to.nil? || callback.nil?
|
274
|
+
log(severity: :error, message: 'initiate_no_required_params', back_to: back_to, callback: callback)
|
241
275
|
halt 400, {'Content-Type' => 'text/plain'}, 'x-ngx-omniauth-initiate-back-to and x-ngx-omniauth-initiate-callback header are required'
|
242
276
|
end
|
243
277
|
|
278
|
+
log(message: 'initiate', adapter_host: adapter_host, back_to: back_to, callback: callback)
|
279
|
+
|
244
280
|
redirect "#{adapter_host}/auth?back_to=#{back_to}&callback=#{callback}"
|
245
281
|
end
|
246
282
|
|
247
283
|
get '/auth' do
|
284
|
+
set_flow_id!
|
285
|
+
|
248
286
|
# TODO: choose provider
|
249
287
|
session[:back_to] = sanitized_back_to_param
|
250
288
|
session[:app_callback] = sanitized_app_callback_param
|
251
|
-
|
289
|
+
|
290
|
+
if session[:back_to] == '' || session[:app_callback] == '' || session[:back_to].nil? || session[:app_callback].nil?
|
291
|
+
log(severity: :error, message: 'auth_invalid_params', back_to: params[:back_to], callback: params[:callback])
|
292
|
+
halt 400, {'Content-Type' => 'text/plain'}, 'back_to or/and app_callback is invalid'
|
293
|
+
end
|
252
294
|
|
253
295
|
if current_user && !adapter_authorization_expired?
|
254
|
-
|
296
|
+
log(message: 'auth_refresh_app', back_to: params[:back_to], callback: params[:callback])
|
255
297
|
update_session!
|
256
298
|
else
|
257
|
-
|
299
|
+
log(message: 'auth', provider: providers[0], back_to: params[:back_to], callback: params[:callback])
|
258
300
|
redirect "#{adapter_host}/auth/#{providers[0]}"
|
259
301
|
end
|
260
302
|
end
|
261
303
|
|
262
304
|
omniauth_callback = proc do
|
305
|
+
|
263
306
|
session[:user_data] = {}
|
264
307
|
|
265
308
|
unless instance_eval(&on_login_proc)
|
309
|
+
log(severity: :warning, message: 'omniauth_callback_forbidden', new_uid: env['omniauth.auth'][:uid])
|
266
310
|
halt 403, {'Content-Type' => 'text/plain'}, 'Forbidden (on_login_proc policy)'
|
267
311
|
end
|
268
312
|
|
313
|
+
log(message: 'omniauth_callback', new_uid: env['omniauth.auth'][:uid])
|
314
|
+
|
269
315
|
session[:logged_in_at] = Time.now.xmlschema
|
270
316
|
update_session! env['omniauth.auth']
|
271
317
|
end
|
@@ -275,6 +321,7 @@ module NginxOmniauthAdapter
|
|
275
321
|
get '/callback' do # app side
|
276
322
|
app_session = decrypt_session_param(params[:session])
|
277
323
|
session.merge!(app_session)
|
324
|
+
log(message: 'app_callback', back_to: session[:back_to])
|
278
325
|
redirect session.delete(:back_to)
|
279
326
|
end
|
280
327
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nginx_omniauth_adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shota Fukumori (sora_h)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -123,6 +123,7 @@ files:
|
|
123
123
|
- LICENSE.txt
|
124
124
|
- README.md
|
125
125
|
- Rakefile
|
126
|
+
- circle.yml
|
126
127
|
- config.ru
|
127
128
|
- example/Procfile
|
128
129
|
- example/nginx-site.conf
|