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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: da45545a31a51031b94607551c7296f3011c3769
4
- data.tar.gz: 79f17b771dffb86ff9527b78a7fbbe14d1a71bf1
3
+ metadata.gz: a96ef0739bfef47af1b4a8fb09debc9c19993268
4
+ data.tar.gz: 44aabb34e2c339f88e49db0bee0d4e192b150466
5
5
  SHA512:
6
- metadata.gz: 84be2b3d973d457a98b52ba75498b3dd84557012dd8fc9ddadeb5e2873fd9a80efb146f2177024214eadbaf1524814869f250c5ce972fce3e5bad3f61aad7714
7
- data.tar.gz: 432c64e9ec6b1953947d6a8ed72e6c4eb019db5cf984cd62de39361c4d594ca7800be2686f25caae168c9b14f5ec24ccf8ae58ff951916ab049129a613687a6d
6
+ metadata.gz: 261454c8ab6c76b725ea4eae8e14f4db6166c5d13e5aefa5f8208014c07c960b970eb941b2a916de39da700e314fedacaf17bd9ff9e13f9e4d4e722eb81be046
7
+ data.tar.gz: 02419d04c5c6a591088fe8c79834d5571bf341e47b91f9d993626b0a5e05b03f3d2349dcd5a2ae661b5758fac43d38c159904d342e204859c4306a21ec8cc7ae
data/Gemfile CHANGED
@@ -5,3 +5,5 @@ gemspec
5
5
 
6
6
  gem 'omniauth-github'
7
7
  gem 'omniauth-google-oauth2'
8
+
9
+ gem 'unicorn'
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # NginxOmniauthAdapter - Use omniauth for nginx `auth_request`
2
2
 
3
+ [![Circle CI](https://circleci.com/gh/sorah/nginx_omniauth_adapter.svg?style=svg)](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
- TBD
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
+ ![](http://img.sorah.jp/2015-10-08_22.55_2s4hy.png)
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
@@ -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
@@ -26,6 +26,7 @@ server {
26
26
  location / {
27
27
  auth_request /_auth/challenge;
28
28
  # Trick - do internal redirection when auth_request says "need auth".
29
+ proxy_intercept_errors off;
29
30
  error_page 401 = /_auth/initiate;
30
31
 
31
32
  # Receive user info from adapter
@@ -1,6 +1,7 @@
1
1
  # vim: ft=nginx
2
2
  worker_processes 1;
3
3
  daemon off;
4
+ pid /tmp/nginx_omniauth_adapter-nginx.pid;
4
5
 
5
6
  error_log stderr;
6
7
 
@@ -13,5 +14,7 @@ http {
13
14
 
14
15
  server_names_hash_bucket_size 128;
15
16
 
17
+ access_log off;
18
+
16
19
  include nginx-site.conf;
17
20
  }
@@ -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
- p [:auth, session]
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
- p [:auth, :update]
296
+ log(message: 'auth_refresh_app', back_to: params[:back_to], callback: params[:callback])
255
297
  update_session!
256
298
  else
257
- p [:auth, :redirect]
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
@@ -1,3 +1,3 @@
1
1
  module NginxOmniauthAdapter
2
- VERSION = "0.2.0"
2
+ VERSION = "1.0.0"
3
3
  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.2.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-09-02 00:00:00.000000000 Z
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