Skip to content
Snippets Groups Projects
Commit 8e3f1fa6 authored by tduehr's avatar tduehr
Browse files

add CAS authentication support

parent 2b4a3bc5
No related branches found
No related tags found
1 merge request!94Ce upstream
......@@ -66,6 +66,7 @@ v 8.2.3
v 8.2.3
- 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)
......
......@@ -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'
......
......@@ -458,6 +458,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)
......@@ -913,6 +917,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 @@ def add_gon_variables
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
......
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 @@ def omniauth_error
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 @@ def handle_omniauth
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 @@ def base_gitlab_url
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 @@
# 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
......
# 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 instalations 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.
\ No newline at end of file
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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment