Skip to content

Commit 511aeaa

Browse files
Merge pull request #275 from NYULibraries/mcain/shibboleth-omniauth
Integrate Shibboleth SSO
2 parents 620d4b9 + 6e9c6ef commit 511aeaa

File tree

12 files changed

+165
-137
lines changed

12 files changed

+165
-137
lines changed

.tool-versions

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ruby 2.7.8
2+
nodejs 18.10.0

Gemfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ gem 'jbuilder'
1010
gem 'jquery-rails'
1111
gem 'mimemagic', github: 'mimemagicrb/mimemagic', ref: '01f92d86d15d85cfd0f20dabd025dcbd36a8a60f'
1212
gem 'mysql2'
13-
gem 'omniauth-nyulibraries', git: 'https://github.com/NYULibraries/omniauth-nyulibraries', branch: 'v2.2.0'
13+
gem 'omniauth'
14+
gem 'omniauth-oauth2'
1415
gem 'rails'
1516
gem 'rainbow'
1617
gem 'rsolr'

Gemfile.lock

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
GIT
2-
remote: https://github.com/NYULibraries/omniauth-nyulibraries
3-
revision: 2a77afefc346669e5a50ff5c84e48a012490dfbc
4-
branch: v2.2.0
5-
specs:
6-
omniauth-nyulibraries (2.2.0)
7-
omniauth-oauth2 (~> 1.2.0)
8-
91
GIT
102
remote: https://github.com/mimemagicrb/mimemagic.git
113
revision: 01f92d86d15d85cfd0f20dabd025dcbd36a8a60f
@@ -434,7 +426,8 @@ DEPENDENCIES
434426
jquery-rails
435427
mimemagic!
436428
mysql2
437-
omniauth-nyulibraries!
429+
omniauth
430+
omniauth-oauth2
438431
puma
439432
rails
440433
rainbow

app/assets/config/manifest.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
//= link_tree ../images
22
//= link_tree ../javascripts
3+
//= link_tree ../stylesheets
34
//= link_directory ../stylesheets .css

app/controllers/application_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def after_sign_out_path_for(resource_or_scope)
3535
end
3636

3737
def logout_path
38-
'https://login.library.nyu.edu/logout'
38+
Settings.LOGOUT_URL || 'https://qa.auth.it.nyu.edu/oidc/logout'
3939
end
4040
private :logout_path
4141
end
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# frozen_string_literal: true
2+
3+
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
4+
before_action :require_valid_omniauth, only: :shibboleth
5+
6+
def shibboleth
7+
Rails.logger.info("OmniauthCallbacksController#shibboleth: #{omniauth.inspect}")
8+
set_user
9+
if @user.persisted?
10+
log_in
11+
else
12+
redirect_to_login
13+
end
14+
end
15+
16+
def failure
17+
redirect_to root_path
18+
end
19+
20+
private
21+
22+
def redirect_to_login
23+
Rails.logger.error(find_message(:failure, kind: 'NYU Shibboleth', reason: 'User not persisted'))
24+
session['devise.shibboleth_data'] = request.env['omniauth.auth']
25+
redirect_to root_path
26+
end
27+
28+
def log_in
29+
sign_in_and_redirect @user, event: :authentication
30+
set_flash_message(:notice, :success, kind: 'NYU Shibboleth')
31+
logger.info(find_message(:success, kind: 'NYU Shibboleth'))
32+
end
33+
34+
def require_valid_omniauth
35+
head :bad_request unless valid_omniauth?
36+
end
37+
38+
def valid_omniauth?
39+
omniauth.present?
40+
end
41+
42+
def omniauth
43+
@omniauth ||= request.env['omniauth.auth']
44+
end
45+
46+
def omniauth_provider
47+
@omniauth_provider ||= omniauth.provider
48+
end
49+
50+
def attributes_from_omniauth
51+
{
52+
provider: omniauth.provider,
53+
username: omniauth.uid,
54+
email: omniauth_email,
55+
firstname: omniauth_firstname,
56+
lastname: omniauth_lastname
57+
}
58+
end
59+
60+
def omniauth_email
61+
@omniauth_email ||= omniauth.info.email
62+
end
63+
64+
def omniauth_firstname
65+
@omniauth_firstname ||= omniauth.info.first_name
66+
end
67+
68+
def omniauth_lastname
69+
@omniauth_lastname ||= omniauth.info.last_name
70+
end
71+
72+
def set_user
73+
# Find existing or initialize new user,
74+
# and save new attributes each time
75+
@user = find_user
76+
@user.update_attributes(attributes_from_omniauth)
77+
end
78+
79+
def find_user
80+
@find_user ||= User.create_from_provider_data(request.env['omniauth.auth'])
81+
end
82+
end

app/controllers/users/omniauth_callbacks_controller.rb

Lines changed: 0 additions & 107 deletions
This file was deleted.

app/models/user.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,21 @@ class User < ActiveRecord::Base
77
# Include default devise modules. Others available are:
88
# :confirmable, :lockable, :timeoutable and :omniauthable
99

10-
devise :omniauthable, omniauth_providers: [:nyulibraries]
10+
devise :omniauthable, omniauth_providers: [:shibboleth]
1111

1212
# Method added by Blacklight; Blacklight uses #to_s on your
1313
# user class to get a user-displayable login/identifier for
1414
# the account.
1515
def to_s
1616
email
1717
end
18+
19+
def self.create_from_provider_data(provider_data)
20+
where(provider: provider_data.provider,
21+
username: provider_data.uid)
22+
.first_or_create do |user|
23+
user.email = provider_data.info.email
24+
user.username = provider_data.uid
25+
end
26+
end
1827
end

config/initializers/devise.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
config.password_length = 8..128
1111
config.reset_password_within = 60.minutes
1212
config.sign_out_via = :get
13-
config.omniauth :nyulibraries, Settings.APP_ID, Settings.APP_SECRET, client_options: {
14-
site: Settings.LOGIN_URL,
15-
authorize_path: '/oauth/authorize'
13+
config.omniauth :shibboleth, Settings.APP_ID, Settings.APP_SECRET, client_options: {
14+
site: (Settings.LOGIN_URL || "https://qa.auth.it.nyu.edu"),
15+
authorize_url: "/oauth2/authorize",
16+
token_url: "/oauth2/token",
1617
}
1718
end
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module OmniAuth
2+
module Strategies
3+
require 'omniauth-oauth2'
4+
class Shibboleth < OmniAuth::Strategies::OAuth2
5+
if defined?(::Rails) && ::Rails.env.development?
6+
silence_warnings do
7+
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
8+
end
9+
end
10+
option :name, :shibboleth
11+
option :authorize_params, { scope: "openid" }
12+
13+
uid do
14+
raw_info["sub"]
15+
end
16+
17+
info do
18+
{
19+
email: raw_info["sub"],
20+
last_name: last_name,
21+
first_name: first_name
22+
}
23+
end
24+
25+
def raw_info
26+
response = access_token.get("/oauth2/userinfo?schema=openid")
27+
Rails.logger.info("Shibboleth raw_info: #{response.parsed}")
28+
@raw_info ||= response.parsed
29+
end
30+
31+
# Extract Last Name from identity
32+
def last_name
33+
@last_name ||= raw_info["lastname"] rescue nil
34+
end
35+
36+
# Extract First Name from identity
37+
def first_name
38+
@first_name ||= raw_info["firstname"] rescue nil
39+
end
40+
41+
def log(level, message)
42+
Rails.logger.send(level, "(#{name}) #{message}")
43+
end
44+
end
45+
end
46+
end

0 commit comments

Comments
 (0)