Tuesday, July 10, 2012

CAS - Restlet Access

Today we had to do another modification to the standard CAS login system. As you might know form my older posts we had to add the possibility of using more than one LDAP in our system and some other modifications in order to view the various login pages depending on where you're coming from.

Exactly this changes need to be considered whenever you have to add some more functionality to your CAS system. like the "Remember-Me" function we introduced lately or in this case as we need to offer login via REST calls.

Despite that, the standard solution would work out of the box without the changes discussed above, we cannot do without them, so we had to propagate our changes through the REST plugin. This means that we had to add a new parameter to the REST login call.

POST /cas/v1/tickets HTTP/1.0

This call needs to be parsed correctly and its values need to be stored in our custom credentials class (DomainUsernamePasswordCredentials or RememberMeDomainUsernamePasswordCredentials) which are able to hold the value for domain and if activated, the "RememberMe" option.

Fortunately adding support for this can be done by changing just a single class, which is the TicketResource. By default this class creates an Instance of  "UsernamePasswordCredentials", which needs to be replaced by one of the custom classes mentioned above.
package org.jasig.cas.integration.restlet;

import org.jasig.cas.authentication.principal.Credentials;
import org.jasig.cas.authentication.principal.RememberMeDomainUsernamePasswordCredentials;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.support.WebRequestDataBinder;

public class DomainTicketResource extends TicketResource {

 private static final Logger log = LoggerFactory.getLogger(DomainTicketResource.class);

 protected Credentials obtainCredentials() {
  final UsernamePasswordCredentials c = new RememberMeDomainUsernamePasswordCredentials();
  final WebRequestDataBinder binder = new WebRequestDataBinder(c);
  final RestletWebRequest webRequest = new RestletWebRequest(getRequest());
  return c;
And that's it basically. The only thing that's missing is to exchange the existing bean definition of TicketResource in restlet-servlet.xml with the definition of DomainTicketResource and it will work.