Commit 009f3861 authored by Daniel Schreiber's avatar Daniel Schreiber
Browse files

Add shibboleth omniauth provider

The provider can be configured using the SHIB_* env variables. It is
possible to map attributes to roles using the SHIB_ROLE_FIELDS env
variable:

assume you have configured your shibboleth SP to provide HTTP_AFFILIATION and
HTTP_SHIB_EP_ENTITLEMENT. Any entry in those two attributes will be
compared to the existing roles in greenlight. If such a role exists, it
will be assigned. If the user has roles assigned which are not mentioned
in those attributes, the roles will be removed from the user.
parent a8252673
Pipeline #34784 failed with stage
......@@ -201,6 +201,8 @@ GEM
omniauth-oauth2 (1.5.0)
oauth2 (~> 1.1)
omniauth (~> 1.2)
omniauth-shibboleth (1.3.0)
omniauth (>= 1.0.0)
omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1)
rack
......@@ -374,6 +376,7 @@ DEPENDENCIES
omniauth-bn-launcher!
omniauth-bn-office365!
omniauth-google-oauth2
omniauth-shibboleth
omniauth-twitter
pagy
pg (~> 0.18)
......@@ -399,3 +402,6 @@ DEPENDENCIES
uglifier (>= 1.3.0)
web-console (>= 3.3.0)
webmock
BUNDLED WITH
1.17.3
......@@ -213,6 +213,41 @@ class SessionsController < ApplicationController
logger.info "Support: Auth user #{user.email} is attempting to login."
if @auth['provider'] == 'shibboleth'
logger.info("Shibboleth login: #{@auth}")
logger.info("Shibboleth info: #{@auth.info}")
logger.info("Shibboleth extra: #{@auth.extra[:raw_info]}")
wanted_roles = []
Rails.application.config.omniauth_shibboleth_role_fields.each{|field|
# multivalue fields have their values joined by ; escaped by \
field_values = @auth.extra.raw_info[field].split(/(?<!\\);/)
field_values.each{|role_name|
# never assign reserved roles
next if Role::RESERVED_ROLE_NAMES.include?(role_name)
r = Role.find_by_name(role_name)
if r
wanted_roles << r
end
}
}
logger.info("wanted_roles: #{wanted_roles}")
current_roles = user.roles.where.not(name: Role::RESERVED_ROLE_NAMES).to_a
logger.info("current_roles: #{current_roles}")
# remove_unwanted_roles
current_roles.each{|r|
if not wanted_roles.include?(r)
logger.info("removing role #{r.name} from #{user.social_uid}")
user.remove_role(r.name)
end
}
# add missing roles
wanted_roles.each{|r|
if not current_roles.include?(r)
logger.info("adding role #{r.name} to #{user.social_uid}")
user.add_role(r.name)
end
}
end
# Add pending role if approval method and is a new user
if approval_registration && !@user_exists
user.add_role :pending
......
......@@ -17,6 +17,12 @@ Rails.application.config.omniauth_twitter = ENV['TWITTER_ID'].present? && ENV['T
Rails.application.config.omniauth_google = ENV['GOOGLE_OAUTH2_ID'].present? && ENV['GOOGLE_OAUTH2_SECRET'].present?
Rails.application.config.omniauth_office365 = ENV['OFFICE365_KEY'].present? &&
ENV['OFFICE365_SECRET'].present?
Rails.application.config.omniauth_shibboleth = ENV['SHIBBOLETH'].present?
Rails.application.config.omniauth_shibboleth = ENV['SHIB_UID_FIELD'].present? &&
ENV['SHIB_NAME_FIELD'].present? &&
ENV['SHIB_SESSION_ID_FIELD'].present? &&
ENV['SHIB_APPLICATION_ID_FIELD'].present? &&
ENV['SHIB_EMAIL_FIELD'].present?
SETUP_PROC = lambda do |env|
OmniauthOptions.omniauth_options env
......@@ -60,6 +66,28 @@ Rails.application.config.middleware.use OmniAuth::Builder do
redirect_uri: redirect,
setup: SETUP_PROC
end
if Rails.application.config.omniauth_shibboleth
if ENV['SHIB_ROLE_FIELDS'].present?
# for example HTTP_AFFILIATION:HTTP_HTTP_SHIB_ORGPERSON_ORGUNITNUMBER
role_fields = ENV['SHIB_ROLE_FIELDS'].split(':')
else
role_fields = []
end
# save for later use in SessionController
Rails.application.config.omniauth_shibboleth_role_fields = role_fields
# construct provider
Rails.application.config.providers << :shibboleth
provider :shibboleth, {
:uid_field => ENV['SHIB_UID_FIELD'],
:name_field => ENV['SHIB_NAME_FIELD'],
:shib_session_id_field => ENV['SHIB_SESSION_ID_FIELD'],
:shib_application_id_field => ENV['SHIB_APPLICATION_ID_FIELD'],
:info_fields => {
:email => ENV['SHIB_EMAIL_FIELD'],
},
:extra_fields => role_fields
}
end
end
end
......
......@@ -73,6 +73,36 @@ LDAP_BIND_DN=
LDAP_PASSWORD=
LDAP_ROLE_FIELD=
# Shibboleth Signin
# Set all of these variables to allow signing via Shibboleth. You should add an
# Apache config like the following one:
# <Location /gl>
#
# ProxyPass "http://127.0.0.1:5000/gl"
# ProxyPassReverse "http://127.0.0.1:5000/gl"
#
# ProxyPreserveHost On
#
# RequestHeader set X-Forwarded-Proto https
# </Location>
#
# <Location /gl/auth/shibboleth/callback>
# AuthType shibboleth
# ShibRequestSetting requireSession 1
# ShibUseHeaders On
# require valid-user
# </Location>
#
# SHIB_UID_FIELD='HTTP_EPPN'
# SHIB_NAME_FIELD='HTTP_HTTP_SHIB_PERSON_COMMONNAME'
# SHIB_SESSION_ID_FIELD='HTTP_SHIB_SESSION_ID'
# SHIB_APPLICATION_ID_FIELD='HTTP_SHIB_APPLICATION_ID'
# SHIB_EMAIL_FIELD='HTTP_HTTP_SHIB_ORGPERSON_EMAILADDRESS'
#
# you can assign multiple fields which contain role names. If Roles with exactly
# the same name exist, they will be assigned
# SHIB_ROLE_FIELDS=HTTP_AFFILIATION:HTTP_SHIB_EP_ENTITLEMENT
#
# Set this to true if you want GreenLight to support user signup and login without
# Omniauth. For more information, see:
#
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment