omniauth-azure-activedirectory 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rubocop.yml +8 -0
  4. data/.rubocop_todo.yml +20 -0
  5. data/.travis.yml +7 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +98 -0
  9. data/Rakefile +22 -0
  10. data/examples/rails-todo-list-app/.gitignore +25 -0
  11. data/examples/rails-todo-list-app/Gemfile +33 -0
  12. data/examples/rails-todo-list-app/README.md +83 -0
  13. data/examples/rails-todo-list-app/Rakefile +3 -0
  14. data/examples/rails-todo-list-app/app/assets/javascripts/application.js +4 -0
  15. data/examples/rails-todo-list-app/app/assets/stylesheets/application.css +2 -0
  16. data/examples/rails-todo-list-app/app/controllers/application_controller.rb +3 -0
  17. data/examples/rails-todo-list-app/app/controllers/home_controller.rb +2 -0
  18. data/examples/rails-todo-list-app/app/controllers/profile_controller.rb +20 -0
  19. data/examples/rails-todo-list-app/app/controllers/sessions_controller.rb +28 -0
  20. data/examples/rails-todo-list-app/app/controllers/signed_in_controller.rb +25 -0
  21. data/examples/rails-todo-list-app/app/controllers/tasks_controller.rb +33 -0
  22. data/examples/rails-todo-list-app/app/models/task.rb +10 -0
  23. data/examples/rails-todo-list-app/app/models/user.rb +58 -0
  24. data/examples/rails-todo-list-app/app/views/home/index.html.haml +4 -0
  25. data/examples/rails-todo-list-app/app/views/layouts/application.html.haml +12 -0
  26. data/examples/rails-todo-list-app/app/views/layouts/signed_in.html.haml +18 -0
  27. data/examples/rails-todo-list-app/app/views/profile/index.html.haml +13 -0
  28. data/examples/rails-todo-list-app/app/views/tasks/index.html.haml +11 -0
  29. data/examples/rails-todo-list-app/bin/bundle +3 -0
  30. data/examples/rails-todo-list-app/bin/rails +4 -0
  31. data/examples/rails-todo-list-app/bin/rake +4 -0
  32. data/examples/rails-todo-list-app/bin/setup +29 -0
  33. data/examples/rails-todo-list-app/config.ru +4 -0
  34. data/examples/rails-todo-list-app/config/application.rb +29 -0
  35. data/examples/rails-todo-list-app/config/boot.rb +3 -0
  36. data/examples/rails-todo-list-app/config/database.yml +25 -0
  37. data/examples/rails-todo-list-app/config/environment.rb +13 -0
  38. data/examples/rails-todo-list-app/config/environments/development.rb +41 -0
  39. data/examples/rails-todo-list-app/config/environments/production.rb +79 -0
  40. data/examples/rails-todo-list-app/config/environments/test.rb +42 -0
  41. data/examples/rails-todo-list-app/config/initializers/assets.rb +11 -0
  42. data/examples/rails-todo-list-app/config/initializers/backtrace_silencers.rb +7 -0
  43. data/examples/rails-todo-list-app/config/initializers/cookies_serializer.rb +3 -0
  44. data/examples/rails-todo-list-app/config/initializers/filter_parameter_logging.rb +4 -0
  45. data/examples/rails-todo-list-app/config/initializers/inflections.rb +16 -0
  46. data/examples/rails-todo-list-app/config/initializers/mime_types.rb +4 -0
  47. data/examples/rails-todo-list-app/config/initializers/omniauth.rb +3 -0
  48. data/examples/rails-todo-list-app/config/initializers/session_store.rb +3 -0
  49. data/examples/rails-todo-list-app/config/initializers/wrap_parameters.rb +14 -0
  50. data/examples/rails-todo-list-app/config/routes.rb +22 -0
  51. data/examples/rails-todo-list-app/db/schema.rb +35 -0
  52. data/examples/rails-todo-list-app/public/404.html +67 -0
  53. data/examples/rails-todo-list-app/public/422.html +67 -0
  54. data/examples/rails-todo-list-app/public/500.html +66 -0
  55. data/examples/rails-todo-list-app/public/favicon.ico +0 -0
  56. data/examples/sinatra-multiple-providers-app/.env +11 -0
  57. data/examples/sinatra-multiple-providers-app/Gemfile +8 -0
  58. data/examples/sinatra-multiple-providers-app/README.md +13 -0
  59. data/examples/sinatra-multiple-providers-app/app.rb +51 -0
  60. data/examples/sinatra-multiple-providers-app/config.ru +45 -0
  61. data/lib/omniauth-azure-activedirectory.rb +23 -0
  62. data/lib/omniauth/azure_activedirectory.rb +24 -0
  63. data/lib/omniauth/azure_activedirectory/version.rb +28 -0
  64. data/lib/omniauth/strategies/azure_activedirectory.rb +329 -0
  65. data/omniauth-azure-activedirectory.gemspec +25 -0
  66. data/spec/fixtures/id_token.txt +1 -0
  67. data/spec/fixtures/id_token_bad_audience.txt +1 -0
  68. data/spec/fixtures/id_token_bad_chash.txt +1 -0
  69. data/spec/fixtures/id_token_bad_issuer.txt +1 -0
  70. data/spec/fixtures/id_token_bad_kid.txt +1 -0
  71. data/spec/fixtures/id_token_bad_nonce.txt +1 -0
  72. data/spec/fixtures/id_token_no_alg.txt +1 -0
  73. data/spec/fixtures/x5c.txt +1 -0
  74. data/spec/fixtures/x5c_different.txt +1 -0
  75. data/spec/omniauth/strategies/azure_activedirectory_spec.rb +222 -0
  76. data/spec/spec_helper.rb +44 -0
  77. metadata +217 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3bf9c2318f06c5ca2724b68b565c5e4b2857284f
4
+ data.tar.gz: a8307ba3e6ea99ad223e941753f9d2520659989b
5
+ SHA512:
6
+ metadata.gz: 615968e81a0cf472d85ca48bce50e2956698b2e64da84e8f4c4c020348c0ad7c8c69650e8902e6c810da78b5dfcc390fe4b613e916cb66982dae36ae66fb0305
7
+ data.tar.gz: 0acbfa64ee9616433f446755934673799abcee69144498cb27ec4945af7612803e3241f55304c02f85276086598ff1bd336cb223601037238ceb4c2a15ac6b63
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ *.log
3
+ .bundle
4
+ coverage
5
+ .powenv
6
+ .rspec
7
+ Gemfile.lock
8
+ pkg/*
9
+ tmp
@@ -0,0 +1,8 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - 'spec/fixtures/**/*'
6
+
7
+ Style/Encoding:
8
+ Enabled: false
@@ -0,0 +1,20 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2015-08-06 14:09:24 -0700 using RuboCop version 0.32.1.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Offense count: 2
9
+ Metrics/AbcSize:
10
+ Max: 19
11
+
12
+ # Offense count: 1
13
+ # Configuration parameters: CountComments.
14
+ Metrics/ClassLength:
15
+ Max: 118
16
+
17
+ # Offense count: 1
18
+ # Configuration parameters: Exclude.
19
+ Style/FileName:
20
+ Enabled: false
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.1
5
+ - 2.2
6
+
7
+ script: bundle exec rake spec
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Micorosft Corporation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,98 @@
1
+ # OmniAuth Azure Active Directory
2
+
3
+ OmniAuth strategy to authenticate to Azure Active Directory via OpenId Connect.
4
+
5
+ Before starting, set up a tenant and register a Web Application at [https://manage.windowsazure.com](https://manage.windowsazure.com). Note your client id and tenant for later.
6
+
7
+ # Installation
8
+
9
+ Add to your Gemfile:
10
+
11
+ ```ruby
12
+ gem 'omniauth-azure-activedirectory'
13
+ ```
14
+
15
+ # Usage
16
+
17
+ If you are already using OmniAuth, adding AzureAD is as simple as adding a new provider to your `OmniAuth::Builder`. The provider requires your AzureAD client id and your AzureAD tenant.
18
+
19
+ For example, in Rails you would add this in `config/initializers/omniauth.rb`:
20
+
21
+ ```ruby
22
+ Rails.application.config.middleware.use OmniAuth::Builder do
23
+ provider :azure_activedirectory, ENV['AAD_CLIENT_ID'], ENV['AAD_TENANT']
24
+ # other providers here
25
+ end
26
+ ```
27
+
28
+ If you are using Sinatra or something else that requires you to configure Rack yourself, you should add this to your `config.ru`:
29
+
30
+ ```ruby
31
+ use OmniAuth::Builder do
32
+ provider :azure_activedirectory, ENV['AAD_CLIENT_ID'], ENV['AAD_TENANT']
33
+ end
34
+ ```
35
+
36
+ When you want to authenticate the user, simply redirect them to `/auth/azureactivedirectory`. From there, OmniAuth will takeover. Once the user authenticates (or fails to authenticate), they will be redirected to `/auth/azureactivedirectory/callback` or `/auth/azureactivedirectory/failure`. The authentication result is available in `request.env['omniauth.auth']`.
37
+
38
+ If you are supporting multiple OmniAuth providers, you will likely have something like this in your code:
39
+
40
+ ```ruby
41
+ %w(get post).each do |method|
42
+ send(method, '/auth/:provider/callback') do
43
+ auth = request.env['omniauth.auth']
44
+
45
+ # Do what you see fit with your newly authenticated user.
46
+
47
+ end
48
+ end
49
+ ```
50
+
51
+ # Auth Hash
52
+
53
+ OmniAuth AzureAD tries to be consistent with the auth hash schema recommended by OmniAuth. [https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema](https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema).
54
+
55
+ Here's an example of an authentication hash available in the callback. You can access this hash as `request.env['omniauth.auth']`.
56
+
57
+ ```
58
+ :provider => "azureactivedirectory",
59
+ :uid => "123456abcdef",
60
+ :info => {
61
+ :name => "John Smith",
62
+ :email => "jsmith@contoso.net",
63
+ :first_name => "John",
64
+ :last_name => "Smith"
65
+ },
66
+ :credentials => {
67
+ :code => "ffdsjap9fdjw893-rt2wj8r9r32jnkdsflaofdsa9"
68
+ },
69
+ :extra => {
70
+ :session_state => '532fgdsgtfera32',
71
+ :raw_info => {
72
+ :id_token => "fjeri9wqrfe98r23.fdsaf121435rt.f42qfdsaf",
73
+ :id_token_claims => {
74
+ "aud" => "fdsafdsa-fdsafd-fdsa-sfdasfds",
75
+ "iss" => "https://sts.windows.net/fdsafdsa-fdsafdsa/",
76
+ "iat" => 53315113,
77
+ "nbf" => 53143215,
78
+ "exp" => 53425123,
79
+ "ver" => "1.0",
80
+ "tid" => "5ffdsa2f-dsafds-sda-sds",
81
+ "oid" => "fdsafdsaafdsa",
82
+ "upn" => "jsmith@contoso.com",
83
+ "sub" => "123456abcdef",
84
+ "nonce" => "fdsaf342rfdsafdsafsads"
85
+ },
86
+ :id_token_header => {
87
+ "typ" => "JWT",
88
+ "alg" => "RS256",
89
+ "x5t" => "fdsafdsafdsafdsa4t4er32",
90
+ "kid" => "tjiofpjd8ap9fgdsa44"
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ # License
97
+
98
+ Copyright (c) Microsoft Corporation. Licensed under the MIT License.
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
5
+ require 'rubocop/rake_task'
6
+
7
+ # This can be run with `bundle exec rake spec`.
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ t.pattern = `git ls-files`.split("\n").select { |f| f.end_with? 'spec.rb' }
10
+ t.rspec_opts = '--format documentation'
11
+ end
12
+
13
+ # This can be run with `bundle exec rake rubocop`.
14
+ RuboCop::RakeTask.new(:rubocop) do |t|
15
+ t.patterns = `git ls-files`.split("\n").select do |f|
16
+ f.end_with?('.rb') && !f.start_with?('examples')
17
+
18
+ end
19
+ t.fail_on_error = false
20
+ end
21
+
22
+ task default: :spec
@@ -0,0 +1,25 @@
1
+ *.rbc
2
+ capybara-*.html
3
+ rspec
4
+ /log
5
+ /tmp
6
+ /public/system
7
+ /coverage/
8
+ /spec/tmp
9
+ **.orig
10
+ rerun.txt
11
+ pickle-email-*.html
12
+ config/secrets.yml
13
+ config/initializers/secret_token.rb
14
+ /vendor/bundle
15
+ .rvmrc
16
+ /vendor/assets/bower_components
17
+ *.bowerrc
18
+ bower.json
19
+ .powenv
20
+ /.bundle
21
+ /db/*.sqlite3
22
+ /db/*.sqlite3-journal
23
+ /log/*
24
+ !/log/.keep
25
+ /tmp
@@ -0,0 +1,33 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '4.2.1'
4
+
5
+ # Stores the todo list.
6
+ gem 'sqlite3'
7
+
8
+ # Templating library for views.
9
+ gem 'haml'
10
+
11
+ # The actual web server.
12
+ gem 'thin'
13
+
14
+ # Rack middleware authentication framework.
15
+ gem 'omniauth'
16
+
17
+ # AzureAD specific strategy for OmniAuth.
18
+ gem 'omniauth-azure-activedirectory'
19
+
20
+ # Loads configurations from .env into ENV hash.
21
+ gem 'dotenv'
22
+
23
+ # Acquires access tokens for resources.
24
+ gem 'adal'
25
+
26
+ # For the front end.
27
+ gem 'sass-rails', '~> 5.0'
28
+ gem 'uglifier', '>= 1.3.0'
29
+ gem 'coffee-rails', '~> 4.1.0'
30
+ gem 'jquery-rails'
31
+ gem 'jbuilder', '~> 2.0'
32
+ gem 'sdoc', '~> 0.4.0', group: :doc
33
+ gem 'turbolinks'
@@ -0,0 +1,83 @@
1
+ Rails, OmniAuth and Graph API
2
+ =============================
3
+
4
+ This is a sample MVC web application that demonstrates user authentication with OmniAuth for Azure Active Directory and RESTful calls to the AzureAD Graph API with ADAL Ruby.
5
+
6
+ ## How to run this sample
7
+
8
+ To run this sample you will need
9
+ - [Ruby](https://www.ruby-lang.org/en/documentation/installation/)
10
+ - [Bundler](http://bundler.io)
11
+ - An internet connection
12
+ - An Azure subscription (a free trial is sufficient)
13
+
14
+ ### Step 1 - Install ADAL from source
15
+ Note: This can and should be removed once ADAL is available on RubyGems. After that point ADAL will be installed along with the other dependencies in step 3.
16
+
17
+ ```
18
+ git clone git@github.com:AzureAD/azure-activedirectory-library-for-ruby
19
+ cd azure-activedirectory-library-for-ruby
20
+ gem build adal.gemspec
21
+ gem install adal
22
+ ```
23
+
24
+ ### Step 2 - Install OmniAuth AzureAD from source
25
+ Note: This can and should be removed once ADAL is available on RubyGems. After that point ADAL will be installed along with the other dependencies in step 3.
26
+
27
+ ```
28
+ git clone git@github.com:AzureAD/omniauth-azure-activedirectory-priv
29
+ cd omniauth-azure-activedirectory-priv
30
+ gem build omniauth-azure-activedirectory.gemspec
31
+ gem install omniauth-azure-activedirectory
32
+ ```
33
+
34
+ ### Step 3 - Install the sample dependencies
35
+
36
+ ```
37
+ cd examples/rails-todo-list-app
38
+ bundle
39
+ ```
40
+
41
+ ### Step 4 - Set up the database
42
+
43
+ ```
44
+ rake db:schema:load
45
+ ```
46
+
47
+ Note: Depending on your host environment, you may need to install a Javascript runtime. We suggest Node.js. Installation will differ by platform.
48
+
49
+ ### Step 5 - Configure the app
50
+
51
+ Open `config/environment.rb` and replace the `CLIENT_ID`, `CLIENT_SECRET` and `TENANT` with your values.
52
+
53
+ ### Step 6 - Set up SSL
54
+
55
+ This step is optional to get the sample running and varies across platform and choice of webserver. Here we will present one set of instructions to accomplish this, but there are many others.
56
+
57
+ Generate a self-signed certificate.
58
+
59
+ ```
60
+ openssl req -new -newkey rsa:2048 -sha1 -days 365 -nodes -x509 -keyout server.key -out server.crt
61
+ ```
62
+
63
+ Get your machine/browser to trust the certificate. This varies wildly by platform.
64
+
65
+ On OSX with Safari or Chrome, double click on `server.crt` in Finder to add it to the keychain and then select 'Trust Always'. In Firefox go to Preferences > Advanced > View Certificates > Import and add `server.crt`.
66
+
67
+ ### Step 7 - Start up Rails
68
+
69
+ This sample uses the Thin webserver to host the app on port 9292.
70
+
71
+ If you generated a certificate in Step 6
72
+
73
+ ```
74
+ bundle exec thin start --port 9292 --ssl --ssl-key-file server.key --ssl-cert-file server.crt
75
+ ```
76
+
77
+ If you want to skip SSL verification (shame!)
78
+
79
+ ```
80
+ bundle exec thing start --port 9292 --ssl --ssl-disable-verify
81
+ ```
82
+
83
+ You may now proceed to https://localhost:9292 to view the application. You may get a warning about the self-signed certificate. This is nothing to worry about, as in production you will not be using self-signed certs.
@@ -0,0 +1,3 @@
1
+ require File.expand_path('../config/application', __FILE__)
2
+
3
+ Rails.application.load_tasks
@@ -0,0 +1,4 @@
1
+ //= require jquery
2
+ //= require jquery_ujs
3
+ //= require turbolinks
4
+ //= require_tree .
@@ -0,0 +1,2 @@
1
+ //= require_tree .
2
+ //= require_self
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery with: :exception
3
+ end
@@ -0,0 +1,2 @@
1
+ class HomeController < ApplicationController
2
+ end
@@ -0,0 +1,20 @@
1
+ class ProfileController < SignedInController
2
+
3
+ # If we have the user's ADAL credentials, then we can get an access token.
4
+ # Otherwise we need to do the auth code flow dance.
5
+ def index
6
+ @profile = user_data_hash(current_user.graph_access_token)
7
+ super
8
+ rescue ADAL::TokenRequest::UserCredentialError
9
+ redirect_to User.authorization_request_url.to_s
10
+ end
11
+
12
+ # @return Hash
13
+ def user_data_hash(access_token)
14
+ headers = { 'authorization' => access_token }
15
+ me_endpt = URI('https://graph.windows.net/me?api-version=1.5')
16
+ http = Net::HTTP.new(me_endpt.hostname, me_endpt.port)
17
+ http.use_ssl = true
18
+ JSON.parse(http.get(me_endpt, headers).body)
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ class SessionsController < ApplicationController
2
+ skip_before_filter :verify_authenticity_token
3
+
4
+ def new
5
+ redirect_to '/auth/azureactivedirectory'
6
+ end
7
+
8
+ def create
9
+ # If the session expires, they still access the same todo list next time
10
+ # that they log in with omniauth.
11
+ user = User.find_by_provider_and_uid(auth_hash['provider'],
12
+ auth_hash['uid'])
13
+ user ||= User.from_omniauth(auth_hash)
14
+ session['user_id'] = user.id
15
+ redirect_to tasks_path
16
+ end
17
+
18
+ def destroy
19
+ reset_session
20
+ redirect_to root_url
21
+ end
22
+
23
+ protected
24
+
25
+ def auth_hash
26
+ request.env['omniauth.auth']
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ # Any controllers that require users to sign in should extend this class.
2
+ class SignedInController < ApplicationController
3
+ before_filter :require_sign_in
4
+ skip_before_filter :verify_authenticity_token
5
+
6
+ def index
7
+ @current_user = current_user
8
+ render :index
9
+ end
10
+
11
+ def require_sign_in
12
+ redirect_to root_path if current_user.nil?
13
+ end
14
+
15
+ def add_auth
16
+ current_user.redeem_code(
17
+ params['code'],
18
+ 'https://localhost:9292/authorize')
19
+ redirect_to profile_index_path
20
+ end
21
+
22
+ def current_user
23
+ User.find_by_id(session['user_id'])
24
+ end
25
+ end