We are seeing errors logged in Drupal like this:

CAS_AuthenticationException: in CAS_Client->validateCAS20() (line 2839 of /data01/d7/sites/all/libraries/CAS/CAS/Client.php).

I noticed in Firefox that after logging in to a site, Firefox seems to save CAS login URLs containing service tickets in its history that it should not be saving. Chrome and Safari do not save these. When someone does not have an existing CAS session and visits one of these URLs, a 500 error and broken layout is returned from Drupal. If they already have a CAS session, there is no error and they are logged in.

Steps to repeat:

1. In Firefox, make sure you do not have an existing CAS session.
2. Next, log into your site at http://mysite.com/cas
3. Visit http://mysite.com/caslogout to log out
3. Open a new tab, begin typing http://mysite.com into the address bar and you will see a result similar to: http://mysite.com/cas?destination=&ticket=ST-566468-txnMAAcI13j0ymxcrtVO-cas
4. Click on this result and you receive a 500 error saying "CAS Authentication failed!"

Expected Results:

If the user does not have an existing CAS session, they should be prompted to log into CAS.

Actual Results:

User receives a 500 response with an error that breaks the site layout. See screenshot

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

emsearcy’s picture

This seems like it might be a regression in Firefox: saving history on 302 redirects (phpCAS issues a 302 from the ticket= URL). I found an old bug (2001) where they seem to have had trouble with this before.

https://bugzilla.mozilla.org/show_bug.cgi?id=102043

They made a test case for it (archived site):

http://www-archive.mozilla.org/quality/browser/front-end/testcases/histo...

vinmassaro’s picture

Good find. Still an issue in Firefox 28. We had a discussion on IRC today about catching these exceptions and doing something more sane.

bkosborne’s picture

OK, so the issue here is that we need to capture exceptions thrown from the phpCAS library, which we aren't doing now. We just hope that the ticket is valid, but if it's not, hell breaks loose. Maybe makes sense to open a new task issue to add exception handling throughout the calls to phpCAS and act accordingly. In this case, we would probably want to display a message to the user indicating that their CAS login is not valid. Should probably expose the exact message to an admin to alter it.

Thoughts?

bkosborne’s picture

Title: Visiting login URL containing service ticket results in 500 error » Visiting login URL containing expired or invalid service ticket results in 500 error
vinmassaro’s picture

@bkosborne: The user is accidentally visiting a URL stored in their Firefox history. If they already have an existing CAS session, it appears that the ticket is tossed out and they are authenticated correctly. I would expect the user to be passed to CAS to login in this case, which would prevent them from seeing an error. I can't speak for the other exception handling.

yalet’s picture

The current behavior is:

Page dies horrendously and spits out raw error output from phpCAS.

The ideal behavior is:

Logs the output from phpCAS (the actual exception) into watchdog
Sets a drupal error for the user telling them their session is invalid. (link to login?)
Set http status header based on errror (optional -- not every bad ticket is a 500, should any be?)
Show a real, themed error page

yalet’s picture

Unfortunately, as I discovered recently, phpCAS spits out the output directly from AuthenticationException::__construct, which means that we have no opportunity to catch it to clean up the output.

phpCAS issue on github:

https://github.com/Jasig/phpCAS/issues/129

bjcooper’s picture

The fact that this causes a 500 server error is troubling to me. I'm looking for a way to catch and handle this more gracefully.

Karthik Bharadwaj’s picture

I get the same issue "CAS Authentication failed" and the page breaks, trying to solve it using cache clear drupal methods. It would be great if there is some solution to this problem.

rafuel92’s picture

I'm still having the same issue, it seems that "phpCAS::forceAuthentication()" of the CAS library goes in loop......

bkosborne’s picture

Status: Active » Needs review
FileSize
1.07 KB

To summarize:

1) phpCAS library may throw an authentication exception, which we are not catching, resulting in the Drupal 500 error page being shown
2) The custom authentication exception class that phpCAS is using will print error information to stdout, with no way to turn off. There's an issue open in the phpCAS GitHub to address this: https://github.com/Jasig/phpCAS/issues/129
3) Worse yet, the exception class provides no way to extract error information from it. Error details are not assigned to any property on the class. The error details ARE written to the debug log if it's enabled though.

So, the best we can do, save for fixing this upstream in phpCAS, is to catch the exception, add a wathdog error that some kind of error occurred, and direct users to the debug log (which probably isn't even enabled). To prevent end users from seeing the printed output that the exception writes, we can redirect the user to the homepage.

Really though, this needs to be fixed in phpCAS to at least allow us to extract details from the exception that we catch.

bkosborne’s picture

Side rant: the complexities of phpCAS library and its legacy code style are some of the reasons we are not using it in the D8 branch :)

bkosborne’s picture

Actually this is better, we can use watchdog_exception to log the exception, which will at least tell us what function and line number threw the exception.

rafuel92’s picture

Ok @bkosborne, thanks, i’ve tested it again and the user is now redirected to home page or at the destination parameter.

vinmassaro’s picture

@bkosborne: this looks good, thanks for the patch. I just had this issue reported, where users had bookmarked CAS authentication URLs like this: https://cas-server.example?service=http://mysite.com/my-path

The destination site has an .htaccess redirect to HTTPS, which was triggering this error every time someone tried to visit one of these bookmarked URLs. Your patch makes this better, but I noticed the first time I visit a URL like this and I'm not authenticated, I get redirected to the home page. If I go to it again, it redirects me to the service URL provided. Any way to make it always go to the service? Thanks!

bkosborne’s picture

@vinmassaro - how did the service URL end up having an http:// protocol instead of https:// if there's an htaccess redirect to force https?

vinmassaro’s picture

@bkosborne: the site was previously HTTP only, then had HTTPS added. Users had bookmarked the CAS login links for ease (always a bad practice but it happens all the time) which points them directly at HTTP. They authenticate to CAS and get sent back to the HTTP URL, then redirected to HTTPS. The service no longer matches which then causes this issue. With this patch they at least don't get the error anymore, but are sent to the home page the first time.

bkosborne’s picture

@vinmassaro I'm not sure how else I can improve the patch without adding more complexity. I think I may commit this as it for now and if you find areas to improve it I'll certainly get those in as well. It's much better if your users bookmark a link to the forced login path instead of the CAS server directly:

https://yoursite.com/cas?destination=/wherever

I'm assuming you're already instructing them to do that but we both know users will find ways to do things in weird ways :)

  • bkosborne committed 922753b on 7.x-1.x
    Issue #2232805 by bkosborne, vinmassaro: Visiting login URL containing...
bkosborne’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.