okta_saml 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,4 @@
1
+ Rails.application.routes.draw do
2
+ get '/saml/init' => 'saml#init'
3
+ match '/saml/consume' => 'saml#consume'
4
+ end
@@ -0,0 +1,11 @@
1
+ require 'rails/generators'
2
+
3
+ class OktaSamlGenerator < Rails::Generators::Base
4
+ def self.source_root
5
+ File.join(File.dirname(__FILE__), 'templates')
6
+ end
7
+
8
+ def generate_config_file
9
+ copy_file 'okta_saml.yml', 'config/okta_saml.yml'
10
+ end
11
+ end
data/lib/okta_saml.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "okta_saml/version"
2
+ require "okta_saml/session_helper"
3
+
4
+ module OktaSaml
5
+ if defined?(Rails) && Rails::VERSION::MAJOR == 3
6
+ require "okta_saml/engine"
7
+ end
8
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module OktaSaml
2
+ VERSION = "0.0.5"
3
+ 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: []