Using an existion JSESSIONID or any other login cookie is the solution i have seen in a few examples. Another option is to aquire a Proxy Ticket for the service you are trying to access and use the session you recieve for further request. You could use a new PT for every request but that would defeat the lightweight ajax solution ;). The initial PT allows you to to access a service without any previous connection to the service.

Cheers,

Joachim

Am 26.07.2010 15:04, schrieb Daniel Earwicker:
I am also interested in that question. I've searched around a bit and this is 
what I have so far (I'm a newcomer to CAS, so would appreciate some expert 
opinions!)

The canonical example:

    $.getJson('/my-service/give-me-data', function(result) {
        // now 'result' is a JS object parsed from the
        // JSON return payload
    });

But myservice needs to know that I'm calling on behalf of a user who's allowed 
to see the data. What can I send it as evidence?

Once signed in, a traditional webapp will constantly round-trip a "session ID". For 
convenience this will be stuck in a cookie so the browser sends it back automatically. For example, 
in Java EE this is called JSESSIONID (as defined in JSR-53). In .NET there's similar stuff. 
Basically a unique number that identifies a record maintained on the server for the duration of the 
logical "session", and in the record there is basically the username. This is not a 
feature of CAS itself.

If I just CAS-enable my-service, and call it as in the above snippet, it will respond 
with a redirect - a header that says "Location:" and refers me to the CAS login 
page. So how do we get logged in?

Now, jQuery knows about this type of thing. See:

http://stackoverflow.com/questions/2961051/cas-authentication-and-redirects-with-jquery-ajax

So jQuery will make a second request to the CAS login page. Assuming the user has previously 
signed in and not yet closed their browser, CAS will have stored its own cookie in the user's 
browser. The browser will send this up to CAS, so the CAS login page will immediately respond 
with another redirect back to the protected service, which jQuery will also interpret, and so 
now my-service will be called again, but this time with an extra URL parameter 
"&ticket=blah", which contains the single use ST. At last my-service can 
validate this ST (another call into CAS, from the server side this time). And it has the 
username safely.

So that kind of works, but there are some downsides:

[1] jQuery's redirection implementation is stymied by browser security rules so 
it can only redirect to a URL the same server, port and protocol. As the CAS 
login page's is on the HTTPS protocol on a particular server, so must all the 
other pieces be on that same server, reached over HTTPS. This is an extra 
restriction relative to the non-AJAX case. Seems unfair!

[2] It's a huge amount of chit-chat going on for each little AJAX call. The 
benefit of AJAX is many lightweight calls to get/set specific information on 
the server. I can't see how you'd want to do this for every separate AJAX call. 
Again, here AJAX appears worse than non-AJAX.

[3] What happens to POST data in all the redirecting? Does jQuery preserve it? 
Is it smart enough to post the data to my-service, then not post it to the CAS 
sign-in page, but then remember to post it again when redirected back to 
myservice? I don't know.

The reason normal web apps have it easier is they only go through that dance 
once, then they have a session ID that they round-trip in their own cookie. No 
more validation after that: if you have the session ID, you can act on behalf 
of the user.

We can mimic this in our AJAX calls. So if my-service is implemented with Java, 
it's looking for a cookie called JSESSIONID in the headers of the requests it 
receives. So in the JS I just need to dig into the browser's cookies, get the 
JSESSIONID for the host page, add it to the headers of every AJAX request I 
make, and my-service will be quite happy to assume I'm acting on behalf of 
someone who signed in.

And I found this example:

http://www.mail-archive.com/[email protected]/msg02163.html

It talks about making sure the JSESSIONID is passed, "manually setting cookie 
headers when we sent the AJAX pings". So I guess that's the same idea.

So in summary, AJAX has nothing much to do with CAS, or vice versa. You only 
have to use CAS to protect a page that can create a new session. You have the 
user visit that page (which will go through normal CAS login), and now you have 
a session ID, which exists in some form that depends entirely on the technology 
you are using to build your application - it's nothing to do with CAS.

In high-level terms, CAS produces a random number (the ST) that can be used 
only once to get the username. So it's single-use proof of sign-on. 
Applications then turn this into something multiple-use, which we call the 
session ID, which is nothing directly to do with CAS. That's what you need to 
pass along with all your AJAX calls. In Java EE, it's the JSESSIONID cookie, 
while in .NET or Ruby it's going to be something else, and in some older apps 
it will be just whatever seemed like a good idea in 1999 *cough*.

But the key point is: this is not CAS's problem to solve.

I'd be very interested to hear if I'm on the right or wrong track with this.


--
Joachim Fritschi
Hochschulrechenzentrum (HRZ)
L1|01 Raum 248
Petersenstr. 30
64287 Darmstadt

Tel. +49 6151 16-5638
Fax. +49 6151 16-3050
E-Mail: [email protected]

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to