okta_saml 0.0.5
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.
- data/LICENSE.txt +22 -0
- data/README.md +67 -0
- data/Rakefile +50 -0
- data/app/controllers/saml_controller.rb +31 -0
- data/app/helpers/okta_application_helper.rb +26 -0
- data/app/models/okta_user.rb +21 -0
- data/config/okta_saml.sample.yml +9 -0
- data/config/routes.rb +4 -0
- data/lib/generators/okta_saml_generator.rb +11 -0
- data/lib/okta_saml.rb +8 -0
- data/lib/okta_saml/constants.rb +11 -0
- data/lib/okta_saml/engine.rb +33 -0
- data/lib/okta_saml/session_helper.rb +42 -0
- data/lib/okta_saml/version.rb +3 -0
- metadata +137 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Jared Branum
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# OktaSaml
|
2
|
+
|
3
|
+
[Okta](http://www.okta.com) is an IDP (Identity Provider) that offers enterprise authentication solutions. Okta works by redirecting visitors to your application to a login page that is hosted by Okta. Upon successful authentication Okta sends a POST request with a SAML payload to a Post Back URL (configured by you at setup). The okta_saml gem helps Ruby on Rails applications communicate with Okta.
|
4
|
+
|
5
|
+
It is an engine that adds the following features to your application
|
6
|
+
|
7
|
+
1. A new helper: okta_authenticate!
|
8
|
+
2. Routes
|
9
|
+
|
10
|
+
- /saml/init: Outbound to Okta
|
11
|
+
- /saml/consume: Handles the Okta POST response
|
12
|
+
|
13
|
+
3. Session Management
|
14
|
+
- The okta_saml gem will create a signed cookie that expires in 120 minutes
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
gem 'okta_saml'
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
$ bundle
|
25
|
+
|
26
|
+
Or install it yourself as:
|
27
|
+
|
28
|
+
$ gem install okta_saml
|
29
|
+
|
30
|
+
## Okta Configuration
|
31
|
+
The following steps will help you integrate your Okta application with the okta_saml gem
|
32
|
+
|
33
|
+
1. When creating your application on Okta use the Template SAML 2.0 App
|
34
|
+
2. When specifying the Post Back URL use your hostname/saml/consume. For example http://www.yourdomain.com/saml/consume. It is important that the Post Back URL is a publically accessible domain. For local development you can use a service such as forwardhq.com to make your localhost port publically accessible
|
35
|
+
|
36
|
+
## Configuration
|
37
|
+
|
38
|
+
1. The idp\_sso\_target\_url should be set to the Embed Link from Okta
|
39
|
+
2. The idp\_cert\_fingerprint needs to be created.
|
40
|
+
|
41
|
+
a. Download the Public certificate from Okta. This can be found from within your application configuration, under the Sign On tab.
|
42
|
+
|
43
|
+
b. Click on the "SAML 2.0 setup instructions for Template SAML 2.0 App".
|
44
|
+
|
45
|
+
c. From that page download the Public certificate.
|
46
|
+
|
47
|
+
d. Run the following command replacing the okta.cert file with the path/name of the downloaded certificate.
|
48
|
+
|
49
|
+
openssl x509 -noout -fingerprint -in "okta.cert"
|
50
|
+
|
51
|
+
e. Copy everything after the "SHA1 Fingerprint=" into the 'okta\_saml.yml' file as the idp_cert_fingerprint
|
52
|
+
|
53
|
+
## Usage
|
54
|
+
|
55
|
+
The following steps are required when using the okta_saml gem
|
56
|
+
|
57
|
+
1. Create an `okta_saml.yml` file in your application's config directory. A sample okta_saml.yml file has been included with this gem in the config directory with some configuration notes
|
58
|
+
2. Add a `before_filter` using okta_authenticate! in the controllers where authentication is required
|
59
|
+
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
1. Fork it
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'OktaSaml'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each{|f| load f}
|
31
|
+
|
32
|
+
require 'rspec/core'
|
33
|
+
require 'rspec/core/rake_task'
|
34
|
+
|
35
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
36
|
+
RSpec::Core::RakeTask.new(:spec)
|
37
|
+
|
38
|
+
task :default => :spec
|
39
|
+
|
40
|
+
namespace :gem do
|
41
|
+
task :build do
|
42
|
+
output = IO.popen("gem build okta_saml.gemspec")
|
43
|
+
a = output.readlines
|
44
|
+
a.keep_if{|line| line =~ /File:/}
|
45
|
+
a[0].match(/File:/)
|
46
|
+
filename = $'.strip
|
47
|
+
# puts `echo #{filename}`
|
48
|
+
puts `gem inabox #{filename}`
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class SamlController < ApplicationController
|
2
|
+
include OktaSaml::SessionHelper, OktaApplicationHelper
|
3
|
+
|
4
|
+
skip_before_filter :okta_authenticate!, :okta_logout
|
5
|
+
|
6
|
+
def init
|
7
|
+
redirect_to(idp_login_request_url(request))
|
8
|
+
end
|
9
|
+
|
10
|
+
def consume
|
11
|
+
response = idp_response(params)
|
12
|
+
response.settings = saml_settings(request)
|
13
|
+
if response.is_valid?
|
14
|
+
sign_in(OktaUser.new({:email => response.name_id}))
|
15
|
+
redirect_to redirect_url
|
16
|
+
else
|
17
|
+
render :text => "Failure"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def redirect_url
|
24
|
+
session[:redirect_url]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Rails override to handle unverified post requests from Okta
|
28
|
+
def handle_unverified_request
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module OktaApplicationHelper
|
2
|
+
|
3
|
+
def idp_response(params)
|
4
|
+
Onelogin::Saml::Response.new(params[:SAMLResponse])
|
5
|
+
end
|
6
|
+
|
7
|
+
def saml_settings(request)
|
8
|
+
settings = Onelogin::Saml::Settings.new
|
9
|
+
|
10
|
+
settings.assertion_consumer_service_url = saml_consume_url(host: request.host)
|
11
|
+
settings.issuer = "http://#{request.port == 80 ? request.host : request.host_with_port}"
|
12
|
+
settings.idp_sso_target_url = SAML_SETTINGS[:idp_sso_target_url]
|
13
|
+
settings.idp_cert_fingerprint = SAML_SETTINGS[:idp_cert_fingerprint]
|
14
|
+
settings.name_identifier_format = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
|
15
|
+
# Optional for most SAML IdPs
|
16
|
+
settings.authn_context = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
|
17
|
+
|
18
|
+
settings
|
19
|
+
end
|
20
|
+
|
21
|
+
def idp_login_request_url(request)
|
22
|
+
idp_request = Onelogin::Saml::Authrequest.new
|
23
|
+
idp_request.create(saml_settings(request))
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class OktaUser
|
2
|
+
attr_accessor :email
|
3
|
+
|
4
|
+
def initialize(params)
|
5
|
+
populate(params)
|
6
|
+
end
|
7
|
+
|
8
|
+
def populate(params)
|
9
|
+
params.each do |k, v|
|
10
|
+
self.send("#{k}=".to_sym, v)
|
11
|
+
end
|
12
|
+
rescue NoMethodError => error
|
13
|
+
p error
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.retrieve_from_cookie(remember_token)
|
17
|
+
return OktaUser.new(:email => remember_token) unless remember_token.blank?
|
18
|
+
return nil
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# Copy this file to the Config directory of your application. Do not put your copy here, put it in your application
|
2
|
+
|
3
|
+
development:
|
4
|
+
idp_sso_target_url: http://www.example.com
|
5
|
+
idp_cert_fingerprint: This is created from your certificate. See the Readme for the command
|
6
|
+
|
7
|
+
test:
|
8
|
+
idp_sso_target_url: http://www.example.com
|
9
|
+
idp_cert_fingerprint: C5:19:85:D9:47:F1:BE:57:08:20:25:05:08:46:EB:27:F6:CA:B7:83
|
data/config/routes.rb
ADDED
data/lib/okta_saml.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
if defined?(Rails)
|
2
|
+
saml = begin
|
3
|
+
YAML::load_file(Rails.root.join("config/okta_saml.yml").to_s)
|
4
|
+
rescue Errno::ENOENT
|
5
|
+
p "Missing okta_saml.yml file in Rails.root/config"
|
6
|
+
end
|
7
|
+
SAML_SETTINGS = {
|
8
|
+
:idp_sso_target_url => saml[Rails.env]['idp_sso_target_url'],
|
9
|
+
:idp_cert_fingerprint => saml[Rails.env]['idp_cert_fingerprint']
|
10
|
+
}
|
11
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ruby-saml'
|
3
|
+
require_relative 'session_helper'
|
4
|
+
|
5
|
+
class ActionController::Base
|
6
|
+
include OktaSaml::SessionHelper
|
7
|
+
|
8
|
+
def okta_authenticate!
|
9
|
+
session[:redirect_url] = params[:app_referer] || "#{request.protocol}#{request.host_with_port}#{request.fullpath}"
|
10
|
+
redirect_to saml_init_path unless signed_in?
|
11
|
+
end
|
12
|
+
|
13
|
+
def okta_logout
|
14
|
+
redirect_to saml_logout_path
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
module OktaSaml
|
20
|
+
class Engine < Rails::Engine
|
21
|
+
def initialize
|
22
|
+
require "okta_saml/constants"
|
23
|
+
Rails.application.config.session_store :active_record_store, :key => '_my_key', :domain=> :all
|
24
|
+
add_engine_helpers
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_engine_helpers
|
28
|
+
ActiveSupport.on_load :action_controller do
|
29
|
+
helper OktaSaml::SessionHelper
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module OktaSaml
|
2
|
+
module SessionHelper
|
3
|
+
def sign_in(user)
|
4
|
+
cookies.signed[:remember_token] = {
|
5
|
+
:value => user.email,
|
6
|
+
:expires => 120.minutes.from_now
|
7
|
+
}
|
8
|
+
current_user = user
|
9
|
+
end
|
10
|
+
|
11
|
+
def signed_in?
|
12
|
+
!current_user.nil?
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_user=(user)
|
16
|
+
@current_user = user
|
17
|
+
end
|
18
|
+
|
19
|
+
def current_user
|
20
|
+
@current_user ||= user_from_remember_token
|
21
|
+
end
|
22
|
+
alias_method :okta_user, :current_user
|
23
|
+
|
24
|
+
def destroy
|
25
|
+
sign_out
|
26
|
+
end
|
27
|
+
|
28
|
+
def sign_out
|
29
|
+
cookies.delete(:remember_token)
|
30
|
+
current_user = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def user_from_remember_token
|
35
|
+
OktaUser.retrieve_from_cookie(remember_token)
|
36
|
+
end
|
37
|
+
|
38
|
+
def remember_token
|
39
|
+
cookies.signed[:remember_token]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: okta_saml
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Michael Hoitomt
|
9
|
+
- Jared Branum
|
10
|
+
- Ed Leung
|
11
|
+
- Luke Fender
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
date: 2013-05-03 00:00:00.000000000 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: rails
|
19
|
+
requirement: !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 3.2.13
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.2.13
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: ruby-saml
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.7.2
|
41
|
+
type: :runtime
|
42
|
+
prerelease: false
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 0.7.2
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rspec-rails
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: geminabox
|
67
|
+
requirement: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
type: :development
|
74
|
+
prerelease: false
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
description: The okta_saml gem helps Ruby on Rails applications communicate with Okta
|
82
|
+
email:
|
83
|
+
- mhoitomt@primedia.com
|
84
|
+
- jbranum@primedia.com
|
85
|
+
- eleung@primedia.com
|
86
|
+
- lfender@primedia.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- app/controllers/saml_controller.rb
|
92
|
+
- app/helpers/okta_application_helper.rb
|
93
|
+
- app/models/okta_user.rb
|
94
|
+
- config/okta_saml.sample.yml
|
95
|
+
- config/routes.rb
|
96
|
+
- lib/generators/okta_saml_generator.rb
|
97
|
+
- lib/okta_saml/constants.rb
|
98
|
+
- lib/okta_saml/engine.rb
|
99
|
+
- lib/okta_saml/session_helper.rb
|
100
|
+
- lib/okta_saml/version.rb
|
101
|
+
- lib/okta_saml.rb
|
102
|
+
- LICENSE.txt
|
103
|
+
- Rakefile
|
104
|
+
- README.md
|
105
|
+
homepage: https://github.com/primedia/okta_saml
|
106
|
+
licenses: []
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
113
|
+
requirements:
|
114
|
+
- - ! '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
hash: -2666229237328805024
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
hash: -2666229237328805024
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 1.8.25
|
132
|
+
signing_key:
|
133
|
+
specification_version: 3
|
134
|
+
summary: The okta_saml gem helps Ruby on Rails applications communicate with Okta.
|
135
|
+
The gem properly contstructs the request to Okta and handles the response back from
|
136
|
+
Okta.
|
137
|
+
test_files: []
|