XML RPC does not work when CAS client module is enabled
taroza - October 2, 2009 - 11:52
| Project: | CAS |
| Version: | 6.x-2.x-dev |
| Component: | Code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | taroza |
| Status: | needs work |
Jump to:
Description
Steps to reproduce:
- Configure the cas client. Require CAS for all pages. Check the "Check to see if a user is allready logged in?".
- Enable services module and some of the services via XML-RPC. Then try to call a service using sessid.
- Submit an XML-RPC request.
- It fails. OK. In the "Redirection settings" don't require CAS for services/xmlrpc
- Submit an XML-RPC request.
- It fails. BAD
I attach a patch.
Mainly the issue is that phpCAS::checkAuthentication() is used instead of phpCAS::isAuthenticated() since we don't want to force the login at that point.
| Attachment | Size |
|---|---|
| cas-isAuthenticated.patch | 444 bytes |

#1
This doesn't seem like an appropriate fix. It sounds like what you want is for xmlrpc's to never "require authentication" because if they fire when a user insn't logged in yet. It seems changing this the way you have it will break the "required authentication" cause a redirect will never be executed. This seems incorrect to me. When a user marks a page (such as user*) as requiring authentication they should in fact be automatically redirected to CAS for login.
So do I understand correctly that what we're looking for here is to perhaps not do this test for XMLRPC, is that right? So a user is not logged in and even the CheckAuthentication hook shouldn't fire for xmrpc requests? Cause if the user is already logged into the drupal site, we should never get this far in the code.
#2
// We're going to try phpCAS auth test
if (!$cas_force_login) {
$logged_in = phpCAS::checkAuthentication();
// Set the login tested cookie
setcookie('cas_login_checked','true');
// We're done cause we're not logged in.
if (!$logged_in) return;
}
For me it does not make sense first to make sure that forced login is not required and then in the next line force it. And I think my patch does exactly that: checks for authentication without forcing to authenticate.
I don't think that XML-RPC should be handled separately. There is the "Redirect settings" for that purpose.
#3
The CheckAuthentication mehod is designed to catch the case when a user logs into CAS separately (a different cas enabled site or moodle or student portgal) and then visits the drupal site for the first time that session. The Checkauthentication method does a quick redirect using the CAS "gateway" method to see if the user is logged in. If the answer is no then the user gets redirected back to the drupal site and the user is not logged in, but if the answer is yes, then the user gets redirected back with a ticket and the user is logged in. The result means that anonymous users can visit the site, but if you happened to be already logged into cas for another purpose, then you'll be logged in to the drupal site the first time you visit it.
Your patch will break this functionality. I suspect the redirect is what's causing the RPC call to fail.
If you don't want to be redirected, then uncheck the "Check to see if a user is authenticated" and this check shouldn't fire.
But logging in the user if they happened to be logged in is a different thing then REQUIRING login for a page. And this is what makes me think we need more here.
#4
I am looking now at the checkAuthentication() and isAuthenticated() implementations in phpCAS.
When a user is authenticated on CAS those two methods are equivalent. And the patch is not doing anything more nor less there.
Now, when a user is not authenticated on CAS (checked with isAuthenticated()) AND $cas_force_login == false, why do we want to require the CAS login page?
In my XML-RPC calls I indeed don't handle redirects, however, I configure the module to exclude /services/xmlrpc from the CAS secured set of pages.
I'm probably missing something in the "gateway" feature of CAS...
#5
The gateway method in CAS does NOT, in fact present a login page. We don't want to require a login page, that part you are correct. The redirection is done to facilitate a login check. If the user is not already logged in on the cas server the cas server simply redirects them back.
Trying to restate: isAuthenticated checks to see if you've used cas to login to THIS site already. checkAuthentication will redirect so that it can test whether you've logged into any CAS site before.
You're correct that this feature (Check to see if a user is already authenticated) needs work before it will support sites that have RPC (that's why I suggested disabling it on your site as a work around). By using the isAuthenticated test you're effectively disabling this feature anyway, so why not just leave the code so it works for others and uncheck the settings box.
I am interested in patches that deal with this problem in a more graceful way. I assume that the xmlRPC paths might come on more urls, so we want a configurable option there? Would you agree?
#6
Do I clearly understand what "Check to see if a user is allready logged in?" does. It will look if I am authenticated on CAS and log me into Drupal automatically. When unchecked it will not log me into Drupal until I press a link "CAS Login". Is this right?
I need that the user is logged in automatically when there is a CAS ticket already released for the current session. Therefore I marked "Check to see if a user is allready logged in?". The same Drupal instance is also the XML-RPC server, so I hide /services/xmlrpc from CAS.
If I can achieve both by simply unmarking the "Check to see if a user is allready logged in?" checkbox, maybe that's the way to go indeed.
#7
Do I clearly understand what "Check to see if a user is allready logged in?" does. It will look if I am authenticated on CAS and log me into Drupal automatically. When unchecked it will not log me into Drupal until I press a link "CAS Login". Is this right?
I need that the user is logged in automatically when there is a CAS ticket already released for the current session. Therefore I marked "Check to see if a user is allready logged in?". The same Drupal instance is also the XML-RPC server, so I hide /services/xmlrpc from CAS.
If I can achieve both by simply unmarking the "Check to see if a user is allready logged in?" checkbox, maybe that's the way to go indeed.
#8
Yes that is the functionality we're talking about, except I'd change the sentence to say: When unchecked it will not log me into Drupal until I press a link "CAS Login" or navigate to a page that "requires login" according to the redirection settings.
The problem is that check performed using a redirect to the cas server for the check, and the immediately redirecting back either with or without a ticket. This is what's breaking XMLRPC. The patch you submitted actually will break this functionality for all of your pages (including XMLRPC) which is why it appears to work for you.
The redirection settings that that you are talking about "hiding from CAS" are about forcing authentication, not about "checking to see if authentication is required". You might require login for admin* for example and then whenever you directly navigated to an admin page rather than getting access denied, you'd get taken to the login page. You might also require login for all pages except the home page. Including services/* in that list does not except it from the check to see if you're logged in.
Consider the home page of your site. You might want anonymous users to be able to access the home page (so you wouldn't want to set it to "require login"), but you would want a user to be automatically logged into your site if they'd already logged into another cas site.
I think we need an "don't do cas on any of these pages" We'd wrap the whole init hook in a test for this. That way we know cas won't interfere with any of your pages you don't want it to. Does that seem reasonable?
#9
I think I start to understand :)
1) So the setting like this works:
2) While the setting like this does not:
In my case, I don't really have anonymous users that will be using the site. So I could get around with setting 1). However, the option 2), in general, should be a more popular setting - why would anyone not want to check if the user is already logged in.
So if I understand well, your proposal of "don't do CAS on any of these pages" option makes a lot of sense to me.
Thanks for your patience to explain me all this!
#10
Yep pretty close.
Option 2 shouldn't be more popular, only because of the Require login. If you "require login" for all your pages then you don't need to "check for it" as well.
The real popular option that's going to be a problem is public facing sites that want to do more of a "Require login for specific pages" (eg. user*, admin*) and "Check to see if a user is already logged in? - Checked. If such a site wanted to use XMLRPC stuff it would certainly break it.
I'll try and get to a patch, but I'm changing the priority since there seems to be a work around here. Perhaps the language next to the checkbox needs some work here to help avoid the confusion. Would welcome some suggestions there.