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
|
||||
- Webhook payload has an added, modified and removed properties for each commit
|
||||
- Fix 500 error when creating a merge request that removes a submodule
|
||||
- Add CAS support (tduehr)
|
||||
|
||||
v 8.2.2
|
||||
- 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 'omniauth', '~> 1.2.2'
|
||||
gem 'omniauth-bitbucket', '~> 0.0.2'
|
||||
gem 'omniauth-cas3', '~> 1.1.2'
|
||||
gem 'omniauth-facebook', '~> 3.0.0'
|
||||
gem 'omniauth-github', '~> 1.1.1'
|
||||
gem 'omniauth-gitlab', '~> 1.0.0'
|
||||
|
|
|
@ -439,6 +439,10 @@ GEM
|
|||
multi_json (~> 1.7)
|
||||
omniauth (~> 1.1)
|
||||
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-oauth2 (~> 1.2)
|
||||
omniauth-github (1.1.2)
|
||||
|
@ -893,6 +897,7 @@ DEPENDENCIES
|
|||
octokit (~> 3.7.0)
|
||||
omniauth (~> 1.2.2)
|
||||
omniauth-bitbucket (~> 0.0.2)
|
||||
omniauth-cas3 (~> 1.1.2)
|
||||
omniauth-facebook (~> 3.0.0)
|
||||
omniauth-github (~> 1.1.1)
|
||||
omniauth-gitlab (~> 1.0.0)
|
||||
|
|
|
@ -10,6 +10,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
before_action :authenticate_user_from_token!
|
||||
before_action :authenticate_user!
|
||||
before_action :validate_user_service_ticket!
|
||||
before_action :reject_blocked!
|
||||
before_action :check_password_expiration
|
||||
before_action :ldap_security_check
|
||||
|
@ -202,6 +203,20 @@ class ApplicationController < ActionController::Base
|
|||
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
|
||||
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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
|
||||
protect_from_forgery except: [:kerberos, :saml]
|
||||
protect_from_forgery except: [:kerberos, :saml, :cas3]
|
||||
|
||||
Gitlab.config.omniauth.providers.each do |provider|
|
||||
define_method provider['name'] do
|
||||
|
@ -42,6 +42,14 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
render 'errors/omniauth_error', layout: "errors", status: 422
|
||||
end
|
||||
|
||||
def cas3
|
||||
ticket = params['ticket']
|
||||
if ticket
|
||||
handle_service_ticket oauth['provider'], ticket
|
||||
end
|
||||
handle_omniauth
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def handle_omniauth
|
||||
|
@ -84,6 +92,12 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
redirect_to new_user_session_path
|
||||
end
|
||||
|
||||
def handle_service_ticket provider, ticket
|
||||
Gitlab::OAuth::Session.create provider, ticket
|
||||
session[:service_tickets] ||= {}
|
||||
session[:service_tickets][provider] = ticket
|
||||
end
|
||||
|
||||
def oauth
|
||||
@oauth ||= request.env['omniauth.auth']
|
||||
end
|
||||
|
|
|
@ -287,6 +287,15 @@ production: &base
|
|||
# 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
|
||||
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',
|
||||
# app_id: 'YOUR_APP_ID',
|
||||
# app_secret: 'YOUR_APP_SECRET',
|
||||
|
@ -324,6 +333,10 @@ production: &base
|
|||
# application_name: 'YOUR_APP_NAME',
|
||||
# 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:
|
||||
# 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['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['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.
|
||||
provider_arguments.concat provider['args']
|
||||
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.
|
||||
provider_arguments << provider['args'].symbolize_keys
|
||||
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
|
||||
- [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
|
||||
- [CAS](cas.md) Configure GitLab to sign in using CAS
|
||||
- [Slack](slack.md) Integrate with the Slack chat service
|
||||
- [OAuth2 provider](oauth_provider.md) OAuth2 application creation
|
||||
- [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