Merge branch 'tduehr/gitlab-ce-cas-support'
This commit is contained in:
commit
9832e60ffb
11 changed files with 144 additions and 1 deletions
|
@ -70,6 +70,7 @@ v 8.2.3
|
||||||
- Enable devise paranoid mode to prevent user enumeration attack
|
- Enable devise paranoid mode to prevent user enumeration attack
|
||||||
- Webhook payload has an added, modified and removed properties for each commit
|
- Webhook payload has an added, modified and removed properties for each commit
|
||||||
- Fix 500 error when creating a merge request that removes a submodule
|
- Fix 500 error when creating a merge request that removes a submodule
|
||||||
|
- Add CAS support (tduehr)
|
||||||
|
|
||||||
v 8.2.2
|
v 8.2.2
|
||||||
- Fix 404 in redirection after removing a project (Stan Hu)
|
- Fix 404 in redirection after removing a project (Stan Hu)
|
||||||
|
|
1
Gemfile
1
Gemfile
|
@ -23,6 +23,7 @@ gem 'devise-async', '~> 0.9.0'
|
||||||
gem 'doorkeeper', '~> 2.2.0'
|
gem 'doorkeeper', '~> 2.2.0'
|
||||||
gem 'omniauth', '~> 1.2.2'
|
gem 'omniauth', '~> 1.2.2'
|
||||||
gem 'omniauth-bitbucket', '~> 0.0.2'
|
gem 'omniauth-bitbucket', '~> 0.0.2'
|
||||||
|
gem 'omniauth-cas3', '~> 1.1.2'
|
||||||
gem 'omniauth-facebook', '~> 3.0.0'
|
gem 'omniauth-facebook', '~> 3.0.0'
|
||||||
gem 'omniauth-github', '~> 1.1.1'
|
gem 'omniauth-github', '~> 1.1.1'
|
||||||
gem 'omniauth-gitlab', '~> 1.0.0'
|
gem 'omniauth-gitlab', '~> 1.0.0'
|
||||||
|
|
|
@ -439,6 +439,10 @@ GEM
|
||||||
multi_json (~> 1.7)
|
multi_json (~> 1.7)
|
||||||
omniauth (~> 1.1)
|
omniauth (~> 1.1)
|
||||||
omniauth-oauth (~> 1.0)
|
omniauth-oauth (~> 1.0)
|
||||||
|
omniauth-cas3 (1.1.3)
|
||||||
|
addressable (~> 2.3)
|
||||||
|
nokogiri (~> 1.6.6)
|
||||||
|
omniauth (~> 1.2)
|
||||||
omniauth-facebook (3.0.0)
|
omniauth-facebook (3.0.0)
|
||||||
omniauth-oauth2 (~> 1.2)
|
omniauth-oauth2 (~> 1.2)
|
||||||
omniauth-github (1.1.2)
|
omniauth-github (1.1.2)
|
||||||
|
@ -893,6 +897,7 @@ DEPENDENCIES
|
||||||
octokit (~> 3.7.0)
|
octokit (~> 3.7.0)
|
||||||
omniauth (~> 1.2.2)
|
omniauth (~> 1.2.2)
|
||||||
omniauth-bitbucket (~> 0.0.2)
|
omniauth-bitbucket (~> 0.0.2)
|
||||||
|
omniauth-cas3 (~> 1.1.2)
|
||||||
omniauth-facebook (~> 3.0.0)
|
omniauth-facebook (~> 3.0.0)
|
||||||
omniauth-github (~> 1.1.1)
|
omniauth-github (~> 1.1.1)
|
||||||
omniauth-gitlab (~> 1.0.0)
|
omniauth-gitlab (~> 1.0.0)
|
||||||
|
|
|
@ -10,6 +10,7 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
before_action :authenticate_user_from_token!
|
before_action :authenticate_user_from_token!
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
|
before_action :validate_user_service_ticket!
|
||||||
before_action :reject_blocked!
|
before_action :reject_blocked!
|
||||||
before_action :check_password_expiration
|
before_action :check_password_expiration
|
||||||
before_action :ldap_security_check
|
before_action :ldap_security_check
|
||||||
|
@ -202,6 +203,20 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_user_service_ticket!
|
||||||
|
return unless signed_in? && session[:service_tickets]
|
||||||
|
|
||||||
|
valid = session[:service_tickets].all? do |provider, ticket|
|
||||||
|
Gitlab::OAuth::Session.valid?(provider, ticket)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless valid
|
||||||
|
session[:service_tickets] = nil
|
||||||
|
sign_out current_user
|
||||||
|
redirect_to new_user_session_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def check_password_expiration
|
def check_password_expiration
|
||||||
if current_user && current_user.password_expires_at && current_user.password_expires_at < Time.now && !current_user.ldap_user?
|
if current_user && current_user.password_expires_at && current_user.password_expires_at < Time.now && !current_user.ldap_user?
|
||||||
redirect_to new_profile_password_path and return
|
redirect_to new_profile_password_path and return
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||||
|
|
||||||
protect_from_forgery except: [:kerberos, :saml]
|
protect_from_forgery except: [:kerberos, :saml, :cas3]
|
||||||
|
|
||||||
Gitlab.config.omniauth.providers.each do |provider|
|
Gitlab.config.omniauth.providers.each do |provider|
|
||||||
define_method provider['name'] do
|
define_method provider['name'] do
|
||||||
|
@ -42,6 +42,14 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||||
render 'errors/omniauth_error', layout: "errors", status: 422
|
render 'errors/omniauth_error', layout: "errors", status: 422
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cas3
|
||||||
|
ticket = params['ticket']
|
||||||
|
if ticket
|
||||||
|
handle_service_ticket oauth['provider'], ticket
|
||||||
|
end
|
||||||
|
handle_omniauth
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def handle_omniauth
|
def handle_omniauth
|
||||||
|
@ -84,6 +92,12 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||||
redirect_to new_user_session_path
|
redirect_to new_user_session_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_service_ticket provider, ticket
|
||||||
|
Gitlab::OAuth::Session.create provider, ticket
|
||||||
|
session[:service_tickets] ||= {}
|
||||||
|
session[:service_tickets][provider] = ticket
|
||||||
|
end
|
||||||
|
|
||||||
def oauth
|
def oauth
|
||||||
@oauth ||= request.env['omniauth.auth']
|
@oauth ||= request.env['omniauth.auth']
|
||||||
end
|
end
|
||||||
|
|
|
@ -287,6 +287,15 @@ production: &base
|
||||||
# arguments, followed by optional 'args' which can be either a hash or an array.
|
# arguments, followed by optional 'args' which can be either a hash or an array.
|
||||||
# Documentation for this is available at http://doc.gitlab.com/ce/integration/omniauth.html
|
# Documentation for this is available at http://doc.gitlab.com/ce/integration/omniauth.html
|
||||||
providers:
|
providers:
|
||||||
|
# See omniauth-cas3 for more configuration details
|
||||||
|
# - { name: 'cas3',
|
||||||
|
# label: 'cas3',
|
||||||
|
# args: {
|
||||||
|
# url: 'https://sso.example.com',
|
||||||
|
# disable_ssl_verification: false,
|
||||||
|
# login_url: '/cas/login',
|
||||||
|
# service_validate_url: '/cas/p3/serviceValidate',
|
||||||
|
# logout_url: '/cas/logout'} }
|
||||||
# - { name: 'github',
|
# - { name: 'github',
|
||||||
# app_id: 'YOUR_APP_ID',
|
# app_id: 'YOUR_APP_ID',
|
||||||
# app_secret: 'YOUR_APP_SECRET',
|
# app_secret: 'YOUR_APP_SECRET',
|
||||||
|
@ -324,6 +333,10 @@ production: &base
|
||||||
# application_name: 'YOUR_APP_NAME',
|
# application_name: 'YOUR_APP_NAME',
|
||||||
# application_password: 'YOUR_APP_PASSWORD' } }
|
# application_password: 'YOUR_APP_PASSWORD' } }
|
||||||
|
|
||||||
|
# SSO maximum session duration in seconds. Defaults to CAS default of 8 hours.
|
||||||
|
# cas3:
|
||||||
|
# session_duration: 28800
|
||||||
|
|
||||||
# Shared file storage settings
|
# Shared file storage settings
|
||||||
shared:
|
shared:
|
||||||
# path: /mnt/gitlab # Default: shared
|
# path: /mnt/gitlab # Default: shared
|
||||||
|
|
|
@ -126,6 +126,10 @@ Settings.omniauth['block_auto_created_users'] = true if Settings.omniauth['block
|
||||||
Settings.omniauth['auto_link_ldap_user'] = false if Settings.omniauth['auto_link_ldap_user'].nil?
|
Settings.omniauth['auto_link_ldap_user'] = false if Settings.omniauth['auto_link_ldap_user'].nil?
|
||||||
|
|
||||||
Settings.omniauth['providers'] ||= []
|
Settings.omniauth['providers'] ||= []
|
||||||
|
Settings.omniauth['cas3'] ||= Settingslogic.new({})
|
||||||
|
Settings.omniauth.cas3['session_duration'] ||= 8.hours
|
||||||
|
Settings.omniauth['session_tickets'] ||= Settingslogic.new({})
|
||||||
|
Settings.omniauth.session_tickets['cas3'] = 'ticket'
|
||||||
|
|
||||||
Settings['shared'] ||= Settingslogic.new({})
|
Settings['shared'] ||= Settingslogic.new({})
|
||||||
Settings.shared['path'] = File.expand_path(Settings.shared['path'] || "shared", Rails.root)
|
Settings.shared['path'] = File.expand_path(Settings.shared['path'] || "shared", Rails.root)
|
||||||
|
|
|
@ -241,6 +241,16 @@ Devise.setup do |config|
|
||||||
# An Array from the configuration will be expanded.
|
# An Array from the configuration will be expanded.
|
||||||
provider_arguments.concat provider['args']
|
provider_arguments.concat provider['args']
|
||||||
when Hash
|
when Hash
|
||||||
|
# Add procs for handling SLO
|
||||||
|
if provider['name'] == 'cas3'
|
||||||
|
provider['args'][:on_single_sign_out] = lambda do |request|
|
||||||
|
ticket = request.params[:session_index]
|
||||||
|
raise "Service Ticket not found." unless Gitlab::OAuth::Session.valid?(:cas3, ticket)
|
||||||
|
Gitlab::OAuth::Session.destroy(:cas3, ticket)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# A Hash from the configuration will be passed as is.
|
# A Hash from the configuration will be passed as is.
|
||||||
provider_arguments << provider['args'].symbolize_keys
|
provider_arguments << provider['args'].symbolize_keys
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,7 @@ See the documentation below for details on how to configure these services.
|
||||||
- [LDAP](ldap.md) Set up sign in via LDAP
|
- [LDAP](ldap.md) Set up sign in via LDAP
|
||||||
- [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, GitLab, and Google via OAuth.
|
- [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, GitLab, and Google via OAuth.
|
||||||
- [SAML](saml.md) Configure GitLab as a SAML 2.0 Service Provider
|
- [SAML](saml.md) Configure GitLab as a SAML 2.0 Service Provider
|
||||||
|
- [CAS](cas.md) Configure GitLab to sign in using CAS
|
||||||
- [Slack](slack.md) Integrate with the Slack chat service
|
- [Slack](slack.md) Integrate with the Slack chat service
|
||||||
- [OAuth2 provider](oauth_provider.md) OAuth2 application creation
|
- [OAuth2 provider](oauth_provider.md) OAuth2 application creation
|
||||||
- [Gmail actions buttons](gmail_action_buttons_for_gitlab.md) Adds GitLab actions to messages
|
- [Gmail actions buttons](gmail_action_buttons_for_gitlab.md) Adds GitLab actions to messages
|
||||||
|
|
62
doc/integration/cas.md
Normal file
62
doc/integration/cas.md
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# CAS OmniAuth Provider
|
||||||
|
|
||||||
|
To enable the CAS OmniAuth provider you must register your application with your CAS instance. This requires the service URL GitLab will supply to CAS. It should be something like: `https://gitlab.example.com:443/users/auth/cas3/callback?url`. By default handling for SLO is enabled, you only need to configure CAS for backchannel logout.
|
||||||
|
|
||||||
|
1. On your GitLab server, open the configuration file.
|
||||||
|
|
||||||
|
For omnibus package:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo editor /etc/gitlab/gitlab.rb
|
||||||
|
```
|
||||||
|
|
||||||
|
For installations from source:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd /home/git/gitlab
|
||||||
|
|
||||||
|
sudo -u git -H editor config/gitlab.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
1. See [Initial OmniAuth Configuration](omniauth.md#initial-omniauth-configuration) for initial settings.
|
||||||
|
|
||||||
|
1. Add the provider configuration:
|
||||||
|
|
||||||
|
For omnibus package:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
gitlab_rails['omniauth_providers'] = [
|
||||||
|
{
|
||||||
|
name: "cas3",
|
||||||
|
label: "cas",
|
||||||
|
args: {
|
||||||
|
url: 'CAS_SERVER',
|
||||||
|
login_url: '/CAS_PATH/login',
|
||||||
|
service_validate_url: '/CAS_PATH/p3/serviceValidate',
|
||||||
|
logout_url: '/CAS_PATH/logout'} }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
For installations from source:
|
||||||
|
|
||||||
|
```
|
||||||
|
- { name: 'cas3',
|
||||||
|
label: 'cas',
|
||||||
|
args: {
|
||||||
|
url: 'CAS_SERVER',
|
||||||
|
login_url: '/CAS_PATH/login',
|
||||||
|
service_validate_url: '/CAS_PATH/p3/serviceValidate',
|
||||||
|
logout_url: '/CAS_PATH/logout'} }
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Change 'CAS_PATH' to the root of your CAS instance (ie. `cas`).
|
||||||
|
|
||||||
|
1. If your CAS instance does not use default TGC lifetimes, update the `cas3.session_duration` to at least the current TGC maximum lifetime. To explicitly disable SLO, regardless of CAS settings, set this to 0.
|
||||||
|
|
||||||
|
1. Save the configuration file.
|
||||||
|
|
||||||
|
1. Restart GitLab for the changes to take effect.
|
||||||
|
|
||||||
|
On the sign in page there should now be a CAS tab in the sign in form.
|
17
lib/gitlab/o_auth/session.rb
Normal file
17
lib/gitlab/o_auth/session.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
module Gitlab
|
||||||
|
module OAuth
|
||||||
|
module Session
|
||||||
|
def self.create(provider, ticket)
|
||||||
|
Rails.cache.write("gitlab:#{provider}:#{ticket}", ticket, expires_in: Gitlab.config.omniauth.cas3.session_duration)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.destroy(provider, ticket)
|
||||||
|
Rails.cache.delete("gitlab:#{provider}:#{ticket}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.valid?(provider, ticket)
|
||||||
|
Rails.cache.read("gitlab:#{provider}:#{ticket}").present?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue