infinite redirection loop between CAS and Drupal

jim_s - August 14, 2008 - 04:52
Project:CAS
Version:6.x-1.0
Component:Miscellaneous
Category:support request
Priority:normal
Assigned:Unassigned
Status:active
Description

I'm using JA-SIG CAS 3.2.1.1 with Drupal 6.3 and the Drupal CAS module 6.x-1.0. Drupal is running under MAMP 1.7.1.

I have the following options set in the CAS config page:

CAS version: 2.0
No certficate verification
Automatic account creation with user hijacking
All pages requiring login (all pages except specific pages, with no pages specified), with no initial or logout page specified
No password/registration URLs
Extract email from LDAP option set

I am correctly redirected to the CAS login page on the initial Drupal request, but then am redirected do Drupal, then redirected back to CAS, back to Drupal, back to CAS, ... The browser eventually blows out of the loop (after about 7 round trips).

I put some debug log messages into the module code. The first time through the module, there is no know user, as expected. The 2nd time through (presumably on return from CAS login) the user is known. Third time through, no user (I'm looking at the $user variable). 4th time through, have a known user again, 5th time through no user again, and on and on.

Any ideas on what could be going on?

Appreciate any help!

#1

metzlerd - August 14, 2008 - 05:05

Haven't extensively tested with 6.3 yet, but here's what I'd like to know.

With debug statements, after you get to the cas user the second time, does the "final check to make sure we have a good user" (as specified in comments) pass?

I won't be back in the office, so can't get a 6.3 environment up until then. I'll try and repsond as best I can before then.

#2

jim_s - August 14, 2008 - 05:37

Yes, when it comes through the code with the user info (ie, on the 2nd, 4th, etc trip), that section of code is hit - the code within the 'if($user->uid && $user->uid > 0)' block. I am logging $user->uid at that point, and am getting the correct uid from the authmap table for the user logged in through CAS.

I appreciate you taking the time to look into this. If there is *anything* else I can do to help, please let me know!

#3

acidtalks - August 15, 2008 - 07:21

Maybe your site is in maintenance mode? I have experienced the infinite redirection when putting Drupal offline. If I change the CAS redirection option back to "specific pages" it works and I get the "Site offline" page.

I'm using CAS module version 6.x-1.0 with Drupal 6.3, too.

#4

jim_s - August 15, 2008 - 16:15

bahnes - thanks for the info. My site is not in maintenance mode, unfortunately - I'd be happy if that were the case and things started working afterward! :-)

Would you be willing to post info about your working setup? I see that you're using CAS 6.x-1.0 and Drupal 6.3. Would you be willing to post your CAS module settings? (the items under Administer:User Settings:CAS Settings) Also, can you possibly share which versions of php, phpCAS, curl, etc you're using? (maybe a phpinfo dump?)

I've tried using both the 'specific pages' and 'all pages' redirection settings, and no matter what I put under 'specific pages', I get no login redirection (whether logged into CAS or not). But when I use 'all pages', I get the infinite-redirection problem.

**EDIT**
this prior statement is not correct - I can specify specific pages for CAS login (ex, node/add) and when I request that page, if I'm not logged into Drupal (as a local Drupal user), I am redirected to CAS, but then get into the infinite redirection loop. If I request a different page (that requires a login), and I'm not logged into Drupal, I'm sent to the Drupal login page, then am sent on to the requested (and not specified as a specific page in the CAS settings) page.
**/EDIT**

I currently have the certificate verification turned off, FWIW - not sure if perhaps that's playing into the situation or not.

I'm in a bad spot w/ this and really need to get it working, if at all possible, or find something that does work in my environment.

I *truly* appreciate your assistance!!

#5

jim_s - August 15, 2008 - 19:02

Incidentally, if it helps, attached is my phpinfo, as well as my CAS Settings page from w/in Drupal.

AttachmentSize
jims_phpinfo.htm_.txt 61.32 KB
jims_cas_settings.htm_.txt 18.04 KB

#6

acidtalks - August 18, 2008 - 07:15

The redirection loop in maintenace mode apears because after CAS login drupal logs out the user and redirects to the front page. Then again the CAS module redirects to the CAS login page and so on.

I tried to fix this by entering "<front>" to the specific pages. But this does not work when you have configured a front page like "node/4". The regexp has a problem with the "/". So entering "node/4" as a specific page helps.

If you change the following line in function cas_login_check() the bug seems to be fixed:

Change:

if ($user->uid) {

To:

if ($user->uid || variable_get('site_offline', 0)) {

Maybe you want to have a separate issue for this?

#7

acidtalks - August 18, 2008 - 07:50

Here are the versions and configurations I use:

PHP version: 5.2.4 (XAMPP 1.6.4)
Drupal CAS module: (6.x-1.0 Development HEAD)
phpCAS version: 0.6.0
CAS server version: 3.2

CAS properties (properties not mentioned here are empty or unselected):

CAS version: 2.0
CAS server: {my hostname}
CAS Port: 8443
CAS uri:/cas
CAS PEM certificate verification: Do not verify the certificate
Should Drupal user accounts be automatically created? Yes
Require CAS login for:all pages except specific pages
Specific pages: admin | user/login

Differences I see are:

  • You are using user hijacking.
  • I'm using Drupal CAS module from HEAD (but 6.x-1.0 has worked).
  • You extract the email from LDAP. I'm using my own module because there are some issues on LDAP sync (see #176841: Problems with CAS and ldap_integration):

I would try to disable user hijacking and email LDAP sync to see if there are some problems.

#8

metzlerd - August 19, 2008 - 03:45

Wouldn't this means that admins could not log in to cas? Seems dangerous, if your admin logins are cas (which mine are). Maybe alternatively we could try putting that in the force cas login test, so that you could still get to /cas/login to login, if you get my meaning. Yes a separate issue might be good.

Woops this was in response to the issue before (about chainging the uid test to include maintenance mode)

#9

jim_s - August 20, 2008 - 16:01

Ok, mystery solved - I had loaded the wrong version of phpCAS. I'd downloaded both 1.0 and 0.6 at some point, and mindlessly loaded 1.0 on my Apache instance. It works great w/ 0.6!

Sorry to take up everyone's time on this. <:-(

#10

metzlerd - August 21, 2008 - 02:17

Good news. I need to find some time to figure out what all these troubles are with 1.0. Would be nice if it didn't keep cropping up.

#11

acidtalks - August 26, 2008 - 15:18

Today I upgraded phpCAS to 1.0.0-RC1 because I needed the Single Sign Out feature. So I ran into the same problem like jim_s and had to look at this again. Please note that I have upgraded to Drupal 6.4.

After a lot of debugging I have found the code that causes the problem. In the CASClient constructor the session id is renamed and phpCAS calls session_destroy().

See client.php from line 500:

if (!$this->isLogoutRequest() && !empty($_GET['ticket'])) {
  // copy old session vars and destroy the current session
  if (!isset($_SESSION)) {
    session_start();
  }
  $old_session = $_SESSION;
  session_destroy();
  // set up a new session, of name based on the ticket
  $session_id = preg_replace('|-|','',$_GET['ticket']);
  phpCAS::LOG("Session ID: " . $session_id);
  session_id($session_id);
  if (!isset($_SESSION)) {
    session_start();
  }
  // restore old session vars
  $_SESSION = $old_session;
  error_log( "client.php: session_id=".session_id());
}

The call to session_destroy() causes PHP to forget about the custom session handlers which Drupal sets by calling session_set_save_handler() in bootstrap.inc. This seems to be a PHP bug: http://bugs.php.net/bug.php?id=32330

So what happens is that drupal deletes the session from the database when session_destroy() is called but the session data is not saved again before cas_login_page() redirects after a successful login. The function drupal_goto() calls session_write_close() which has no effect any more.

Here are the files that are important if you try to reproduce the steps above:

cas.module
client.php, line 506
bootstrap.inc, line 980
common.inc, line 323

I could work around this problem by inserting the following lines in cas.module after phpCAS::client():

session_set_save_handler('sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy_sid', 'sess_gc');
session_start();

Another way could be to remove session_destroy() from phpCAS. I have also filed a ticket at phpCAS to see what they think about this: http://www.ja-sig.org/issues/browse/PHPCAS-26

Because my knowledge about PHP session handling is not so far-reaching I would like to hear your opinion.

#12

acidtalks - October 16, 2008 - 07:03

It seems that phpCAS 1.0.1 fixes this issue. I have successfully tested this version with CAS-6.x-1.0.

see: http://www.ja-sig.org/issues/browse/PHPCAS-26

#13

madsph - February 20, 2009 - 10:52

I am also experiencing this problem, and am really stuck.

My problem is quite weird actually, since I have developed the site on a windows machine which is working with out any problems at all. But after moving to my Linux production platform, I get this infinite loop.

Both systems use the same CAS server.
The drupal cas module and the phpCas (1.0.1) versions are the same for both machines (copied directly from my windows box to the production server).

According to the status report the differences of the two installations are these:

Component                    Production                    Development
GD library                   2.0 or higher                 bundled (2.0.34 compatible)
MySQL database               5.0.32                        5.0.27
PHP                          5.2.0-8+etch13                5.2.8
PHP memory limit             64M                           128M
Web server                   Apache/2.2.3 (Debian)         Apache/2.2.11
                             PHP/5.2.0-8+etch13            (Win32) PHP/5.2.8

I can't see that any of these differences should cause the problem.
Does any one know of any thing else I could check?

#14

metzlerd - February 20, 2009 - 14:57

Assuming the development environment and production environment use different databases, could you do a comparison of CAS settings between the production and development environment? I've never been able to reproduce this bug, but am willing to try.

It would be also good to know which version of Drupal you're using.

#15

madsph - February 23, 2009 - 07:09

Both installations are using drupal 6.9.

The CAS settings are identical on both servers:
CAS version: 2.0
CAS server: myserver.mydomain
CAS port: 443
CAS PEM certificate verification: Do not verify the certificate
If Drupal is not the user repository, should cas highjack users with the same name? true
Should Drupal user accounts be automatically created? true
Email Domain: my_mail_domain
Users canot change email address: true
Users canot change password: true
Auto-assign users to the role(s): authenticated user
Require CAS login for: all pages except specific pages
Specific pages: [blank] (well - I had to but the admin pages here for the broken server in order to get back to the CAS settings ;-) )
Force redirection on initial login: false
Initial login landing page: [blank]
Successful login message: Logged in via CAS as %cas_username.
Redirect user on logout: false
Logout destination: [blank]
Change password URL: [blank]
Registration URL: [blank]
Should we extract the user email from an LDAP directory? false
Email attribute: mail
Should we extract user groups from an LDAP directory? false

As I said it is really weird, I have set up CAS three times (on environments like my working windows platform) with out any problems at all.

Thanks
madsph

#16

metzlerd - February 23, 2009 - 17:28

So no differences between dev and prod. Something else to check.

Are Clean URL's enabled on the linux box? Are allowOverrides enabled on apache? And finally did the .htaccess file get moved to the production box (this is often treated as a hidden file and doesn't get copied).

Dave

#17

madsph - February 24, 2009 - 11:25

Yes clean urls are activated and working on both servers. As you guessed the .htaccess file was omitted first, but since it prevented me from activating clean urls that was soon fixed :-)

When I look in my log after a failed attempt to use CAS I get something like this:

user 02/20/2009 - 08:52 Session opened for mph. mph
user 02/20/2009 - 08:52 Session opened for mph. mph
user 02/20/2009 - 08:52 Session opened for mph. mph
user 02/20/2009 - 08:52 Session opened for mph. mph
user 02/20/2009 - 08:52 Session opened for mph. mph
user 02/20/2009 - 08:52 Session opened for mph. mph
user 02/20/2009 - 08:52 Session opened for mph. mph

In this case my browser bailed out after 7 redirection attempts.

As you can see the every time the user is redirected back from CAS my drupal site actually acknowledges the token and opens a session for the user, but for some reason it feels the need to ask for a new token without closing the session for the user, or at least, if it is closing the session it is doing so without logging it.

EDIT:

I have tried to isolate the problem now. So on my linux server I made a fresh drupal installation using the .htaccess file and the cas module from my working installation. Just to be sure that some obscure combination of modules and rules doesn't trigger this behavior. Clean URLs are switched on and working, but apart form this no other configuration is made.

In this installation I still get the infinite redirection loop :-(

Could this be caused by the apache server which is a slightly older version compared to the working server (2.2.3 compared to 2.2.11). I have other sites running on my production apache so upgrading it to 2.2.11 is not really a good option for me right now. Has any one else had it working on linux and apache 2.2.3?

#18

jlevis - July 15, 2009 - 18:38

Make sure your server has cURL installed.

I had the infinite loop problem when trying to use a CAS plugin on a Wordpress installation. I was able to fix it when I realized the server didn't have cURL which is specified as a requirement for PHPCas.

I hope that helps.

#19

madsph - July 28, 2009 - 10:34

Thank you for the hint. cURL was not installed, but unfortunately it didn't solve the issue. I do think this is the right track though, so I will go ahead and verify the rest of the installation.

 
 

Drupal is a registered trademark of Dries Buytaert.