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
Comment | File | Size | Author |
---|---|---|---|
#13 | catch-cas-authentication-exception-2232805-14.patch | 981 bytes | bkosborne |
| |||
cas_exception.png | 27.23 KB | vinmassaro |
Comments
Comment #1
emsearcy CreditAttribution: emsearcy commentedThis 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...
Comment #2
vinmassaro CreditAttribution: vinmassaro commentedGood find. Still an issue in Firefox 28. We had a discussion on IRC today about catching these exceptions and doing something more sane.
Comment #3
bkosborneOK, 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?
Comment #4
bkosborneComment #5
vinmassaro CreditAttribution: vinmassaro commented@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.
Comment #6
yalet CreditAttribution: yalet commentedThe 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
Comment #7
yalet CreditAttribution: yalet commentedUnfortunately, 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
Comment #8
bjcooper CreditAttribution: bjcooper commentedThe 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.
Comment #9
Karthik Bharadwaj CreditAttribution: Karthik Bharadwaj commentedI 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.
Comment #10
rafuel92 CreditAttribution: rafuel92 as a volunteer commentedI'm still having the same issue, it seems that "phpCAS::forceAuthentication()" of the CAS library goes in loop......
Comment #11
bkosborneTo 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.
Comment #12
bkosborneSide 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 :)
Comment #13
bkosborneActually 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.
Comment #14
rafuel92 CreditAttribution: rafuel92 as a volunteer and at Ibuildings commentedOk @bkosborne, thanks, i’ve tested it again and the user is now redirected to home page or at the destination parameter.
Comment #15
vinmassaro CreditAttribution: vinmassaro commented@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!
Comment #16
bkosborne@vinmassaro - how did the service URL end up having an http:// protocol instead of https:// if there's an htaccess redirect to force https?
Comment #17
vinmassaro CreditAttribution: vinmassaro commented@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.
Comment #18
bkosborne@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 :)
Comment #20
bkosborne