DokuWiki

It's better when it's simple

User Tools

Site Tools


auth:cas

This is an old revision of the document!


CAS Authentication Backend

This module allows authentication against a CAS server. It is designed as an extension of the LDAP backend so CAS can be used for authentication and LDAP for ACL management.

It requires a small modification of two one DokuWiki files.

Easy Way

Installation

Getting the scripts

First of all, download this zip : dokuwiki_inc.zip

The inc folder correspond to your dokuwiki inc folder.

This archive contain cas.class.php and a modified phpCAS library. I just changed the way session are managed in the phpCAS lib. These changes will be implemented soon in the official phpCAS lib.

Unpack this archive in your dokuwiki folder.

Requirements

The phpCas library needs

  • CURL 7.5+
  • PHP 4.3.1+, PEAR DB
  • Apache 2.0.44+

CURL libs must be present on your system, and they must have been compiled with SSL support. More informations on phpCas requirements

File to modify

In inc/actions.php :

Replace :

function act_auth($act){
  global $ID;
  global $INFO;

By:

function act_auth($act){
    global $ID;
    global $INFO;
	global $auth;
 
	if($auth->cando['login'] && $act == 'login') {
		$auth->logIn();
	}

Configuration

Here is an example of conf/local.php :

$conf['authtype'] = 'cas';
 
//....
 
//---------- CAS config ----------
$conf['auth']['cas']['server'] = 'cas.mdl29.net';
$conf['auth']['cas']['rootcas'] = '/';
$conf['auth']['cas']['port'] = '443';
$conf['auth']['cas']['autologin'] = '1';
$conf['auth']['cas']['handlelogoutrequest'] = '1';
$conf['auth']['cas']['handlelogoutrequestTrustedHosts'] = Array("cas.mdl29", "cas.mdl29", "castest.mdl29", "cas2.mdl29", "cas3.mdl29");
$conf['auth']['cas']['caslogout'] = '1';
$conf['auth']['cas']['logFile']="/var/www/Dokuwiki/inc/auth/phpCAS.log"; //Enable debugging

In this example, Single Sign Out is handle thanks to the modified version of phpCAS lib which allow phpCAS to destroy a session even if the service had start one before.

You have to list CAS hosts that will have the right to send logout requests, if your CAS hosts in not in that list his logout requests will be rejected.

To test if everything is ok you can set a log file, this will output phpCAS logs.

This tutorial was entirely test on last DokuWiki version (Angua)

Benjamin BERNARD (Maison du libre Brest) 2012/02/19 18:46

Alternatives

ggauth and plain

I created a similar auth backend in June. Mine uses plain authentication as its source and also ggauth so that I can manage groups locally while only doing the authentication through CAS. The code is pretty similar to what is below.

Here is a link: http://wiki.cornempire.net/doku.php?id=dokuwikicas:start

Note for Cornempire: If you need Single Sign Out you must put this in your login ACT

if ($ACT == 'login') {
    phpCAS::setFixedServiceURL('http://{YOUR CAS LOGIN SERVICE}?service={YOUR WIKI URL}/doku.php?' . $_SERVER["QUERY_STRING"]);
    phpCAS::handleLogoutRequests(true, array("server1.domain.edu", "server2.domain.edu"));    
    phpCAS::forceAuthentication();
}

Just plain

In order to simplify my installation of DokuWiki, I have written a new SSOCAS plugin using CAS only for password authentication. — nineworlds 2010/05/11 10:49

Installation

Download the following zip file and extract it to the inc/auth directory. It contains the phpCas library files and the cas.class.php file

Files to install

I cannot upload the file, so here is the content of the cas.class.php file (inspired from this site). Place this file in the inc/auth directory :

cas.class.php
<?php
/**
 * Inspired from 
 * http://www.esup-portail.org/display/PROJDOCUWIKICAS/CASification+de+Docuwiki;jsessionid=58187C0F5A8834D07E6D7F1EB30744C2
 */
 
require_once(DOKU_INC.'inc/auth/ldap.class.php');
include_once('CAS.php');
 
global $conf;
 
class auth_cas extends auth_ldap {
	public $cnfcas = null;
 
    function __construct() {
        global $conf;
 
        parent::__construct();
        $this->cnfcas = $conf['auth']['cas'];
        $this->cando['external'] = true;
        $this->cando['login'] = true;
        $this->cando['logoff'] = true;
 
        // curl extension is needed
        if(!function_exists('curl_init')) {
            if ($this->cnf['debug'])
                msg("CAS err: CURL extension not found.",-1,__LINE__,__FILE__);
            $this->success = false;
            return;
        }
 
        phpCAS::client(CAS_VERSION_2_0, $this->cnfcas['server'], (int) $this->cnfcas['port'],
                        $this->cnfcas['rootcas']);
 
        // automatically log the user when there is a cas session opened
        if($this->cnfcas['autologin']) {
            phpCAS::setCacheTimesForAuthRecheck(1);
        }
        else {
            phpCAS::setCacheTimesForAuthRecheck(-1);
        }
 
        if($this->cnfcas['cert']) {
            phpCAS::setCasServerCert($this->cnfcas['cert']);
        }
        elseif($this->cnfcas['cacert']) {
            phpCAS::setCasServerCACert($this->cnfcas['cacert']);
        }
        else {
            phpCAS::setNoCasServerValidation();
        }
 
        if($this->cnfcas['handlelogoutrequest']) {
            phpCAS::handleLogoutRequests();
        }
        else {
            phpCAS::handleLogoutRequests(false);
        }
    }
 
    public function trustExternal($user,$pass,$sticky=false) {
        global $USERINFO;
        global $conf;
 
        $sticky ? $sticky = true : $sticky = false; //sanity check
 
        $session = $_SESSION[$conf['title']]['auth'];
 
        if(phpCAS::checkAuthentication()) {
            $user = phpCAS::getUser();
 
            if(isset($session)) {
                $_SERVER['REMOTE_USER'] = $user;
                $USERINFO = $session['info'];
                $USERINFO['grps'][] = $conf['defaultgroup'];
                $_SESSION[$conf['title']]['auth']['user'] = $user;
                $_SESSION[$conf['title']]['auth']['pass'] = $session['pass'];
                $_SESSION[$conf['title']]['auth']['info'] = $USERINFO;
                $_SESSION[$conf['title']]['auth']['buid'] = $session['buid'];
            }
            else {
                $USERINFO = $this->getUserData($user);
                $_SERVER['REMOTE_USER'] = $user;
                $_SESSION[$conf['title']]['auth']['user'] = $user;
                $_SESSION[$conf['title']]['auth']['pass'] = $pass;
                $_SESSION[$conf['title']]['auth']['info'] = $USERINFO;
                $_SESSION[$conf['title']]['auth']['buid'] = auth_browseruid();
            }
 
            return true;
        }
 
        return false;
    }
 
    public function logIn() {
        global $QUERY;
 
        phpCAS::setFixedServiceURL(DOKU_URL . 'doku.php?id=' . $QUERY);
        phpCAS::forceAuthentication();
    }
 
    public function logOff() {
        global $QUERY;
 
        if($this->cnfcas['caslogout']) { // dokuwiki + cas logout
            @session_start();
            session_destroy();
            phpCAS::logoutWithRedirectService(DOKU_URL . 'doku.php?id=' . $QUERY);
        }
        else { // dokuwiki logout only
            @session_start();
            session_destroy();
        }
    }
}
//Setup VIM: ex: et ts=4 enc=utf-8 :

The phpCas library can be downloaded here. Place the CAS directory and its content in the inc/auth directory.

Requirements

The phpCas library needs

  • CURL 7.5+
  • PHP 4.3.1+, PEAR DB
  • Apache 2.0.44+

CURL libs must be present on your system, and they must have been compiled with SSL support. More informations on phpCas requirements

Files to modify

Edit the file inc/auth/basic.class.php and replace

'logoff'      => false, // has the module some special logoff method?

by

'logoff'      => false, // has the module some special logoff method?
'login'       => false, // has the module some special login method?

Edit the file inc/actions.php and replace :

function act_auth($act){
  global $ID;
  global $INFO;

by :

function act_auth($act){
  global $ID;
  global $INFO;
  global $auth;
 
  if($auth->cando['login'] && $act == 'login') {
    $auth->logIn();
  }

Configuration

This is an example configuration to set in your conf/local.php to authenticate against your CAS server.

$conf['authtype'] = 'cas';
 
/* CAS specific configuration */
$conf['auth']['cas']['server'] = 'cas.server.tld';
$conf['auth']['cas']['port'] = 443;
// CAS server root parameter
$conf['auth']['cas']['rootcas'] = 'cas';
// automatically log the user when there is already a CAS session opened
$conf['auth']['cas']['autologin'] = 1;
// log out from the CAS server when loggin out from dokuwiki
$conf['auth']['cas']['caslogout'] = 1;
// log out from dokuwiki when loggin out from the CAS server (should work with CASv3, experimental)
$conf['auth']['cas']['handlelogoutrequest'] = 0;
 
/* LDAP usual configuration */
$conf['auth']['ldap']['server']      = 'ldap://server.tld:389';
$conf['auth']['ldap']['usertree']    = 'ou=People, dc=server, dc=tld';
$conf['auth']['ldap']['grouptree']   = 'ou=Group, dc=server, dc=tld';
$conf['auth']['ldap']['userfilter']  = '(&(uid=%{user})(objectClass=posixAccount))';
$conf['auth']['ldap']['groupfilter'] = '(&(objectClass=posixGroup)(|(gidNumber=%{gid})(memberUID=%{user})))';

Discussion

  • Edit inc/auth/basic.class.php for add 'login' ⇒ false is really usefull? This value is override in cas.class.php

If you don't add this in basic auth, then

  if($auth->cando['login'] && $act == 'login') {
    $auth->logIn();
  }

can look for an undefined index.

  • in cas.class.php : to have automatic redirection to cas server if not already logged :
    public function trustExternal($user,$pass,$sticky=false) {                
        global $USERINFO;                                                     
        global $conf;                                                         
                                                                              
        $sticky ? $sticky = true : $sticky = false; //sanity check            
                                                                              
        $session = $_SESSION[$conf['title']]['auth'];                         
                                                                              
        if(phpCAS::checkAuthentication()) {                                   
            $user = phpCAS::getUser();                                        
                                                                              
            if(isset($session)) {                                             
                $_SERVER['REMOTE_USER'] = $user;                              
                $USERINFO = $session['info'];                                 
                $_SESSION[$conf['title']]['auth']['user'] = $user;            
                $_SESSION[$conf['title']]['auth']['pass'] = $session['pass']; 
                $_SESSION[$conf['title']]['auth']['info'] = $USERINFO;        
                $_SESSION[$conf['title']]['auth']['buid'] = $session['buid']; 
            }                                                                 
            else {                                                            
                $USERINFO = $this->getUserData($user);                        
                $_SERVER['REMOTE_USER'] = $user;                              
                $_SESSION[$conf['title']]['auth']['user'] = $user;            
                $_SESSION[$conf['title']]['auth']['pass'] = $pass;            
                $_SESSION[$conf['title']]['auth']['info'] = $USERINFO;        
                $_SESSION[$conf['title']]['auth']['buid'] = auth_browseruid();
            }                                                                 
                                                                              
            return true;                                                      
        }                                                                     
        else {                                                                
                 phpCAS::forceAuthentication();                                            
        }                                                                     
                                                                              
        return false;                                                         
    }                                                        

I just added the part :

        else {                                                                
          phpCAS::forceAuthentication();                                                                                 
        }                                                                     
  • Problem with upgrade of phpcas 1.1.3 :

Hello, I've upgraded phpcas :

# pear upgrade http://downloads.jasig.org/cas-clients/php/1.1.3/CAS-1.1.3.tgz

when I go to my wiki, I've got the following error page :-( :

phpCAS error: phpCAS::client(): Another session was started before phpcas. Either disable the session handling for phpcas in the client() call or modify your application to leave session handling to phpcas in /opt/web/Web/wiki-2009-12-25.cas/inc/auth/cas.class.php on line 34

If I downgrade phpcas, it's ok as before. Frantz 2010/10/25

(by Evaldas, 2011/01/15)

To solve phpCAS session error (for phpCAS v1.1.3+) insert “,false” on line 33 in inc/auth/cas.class.php so that it looks like this:

                        $this->cnfcas['rootcas'], false);
Problem remains

There is a problem with the latest version of phpCAS (1.2.1) and DokuWiki (dokuwiki-latest.tgz) even after making the changes mentioned before. In fact, when we log in with CAS server, an error page occurs in web browser with the following message “This can occur when you open a page that is redirected to another page which is in turn redirects to the original page.” then a phpCAS error message like this “CAS Authentication failed!”.

How can we solve this error?

If you know how to solve this problem, please contribute.

—05/05/11

auth/cas.1353061269.txt.gz · Last modified: 2012-11-16 11:21 by 141.64.161.15

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki