Float Mobile Learning – Connecting iOS, Drupal and CAS Float Mobile Learning TM

Blog

Our Expertise

Connecting iOS, Drupal and CAS

Our sister company, The Iona Group,  just finished a highly innovative project for Loyola Marymount University in Los Angeles. The project is centered around student interaction (sending messages, uploading photos/video, etc.) with the expectation that a bulk of the interaction will come from students on their mobile devices. As part of their larger digital communications strategy and technical infrastructure, we worked with them to understand the audience’s primary device platform and deliver a solution that fit in with their campus technology landscape. The primary user base was identified as iOS devices, since, as with many university campuses nationwide, Apple products are very popular at LMU. This did present some wrinkles to our initial plan to use the mobile web to interact with the installation. Due to the inability to upload files through Mobile Safari on iOS devices, we had to create an iPhone application that bridged the gap.

Moving from initial strategy to implementation planning it was uncovered that LMU is transitioning towards using CAS (Central Authentication Service) in all their web applications. CAS is a single sign-on protocol developed by Yale University and is now a project of Jasig. The content management for this newly developed project by Iona is handled entirely by Drupal. Fortunately, there is a Drupal module (appropriately named CAS) which integrates the wonderful phpCAS library with the Drupal authentication system. Our task was to find a way to integrate CAS authentication into our iPhone application and pass that authentication off to Drupal. It wasn’t immediately clear on how to stitch the various pieces together, and we see alot of applicability of this code, especially in academic settings, so let’s examine how this works. Maybe you’ll find this useful in getting an app up and running for your users!

Step 1: Getting a Service Ticket

CAS is primarily designed to provide a single sign-on service to web applications. Fortunately, CAS also has a RESTful API that allows our iOS application to access it and authenticate for another service. This process involves passing the username and password to the CAS service, obtaining a ticket-granting ticket (letting us know that the login was successful), and using the ticket-granting ticket to generate a service ticket for a specified service (in this case, the URL to our Drupal site).

This process needs to happen within the iOS application. The user will enter his or her username and password and the iOS application needs to receive the ticket-granting ticket. We’re going to use ASIHTTPRequest, a wrapper for the CFNetwork API, because it makes communication with a server a lot easier to understand.

//Create the request
NSString *server 	= @"https://example.com/cas/v1/tickets"; //The URL to REST on the CAS authentication server
NSString *theUsername 	= @"username";
NSString *thePassword 	= @"password";
ASIHTTPRequest *request	= [ASIHTTPRequest requestWithURL:[NSURL URLWithString:server]];

//Format the credentials
NSString *credentials	= [NSString stringWithFormat:@"username=%@&password=%@",theUsername,thePassword];

//Add the credentials to the body of the request as per
//https://wiki.jasig.org/display/CASUM/RESTful+API#RESTfulAPI-RequestforaTicketGrantingTicketResource
[request appendPostData:[credentials dataUsingEncoding:NSUTF8StringEncoding]];
[request setRequestMethod:@"POST"];
[request setValidatesSecureCertificate:NO];

//Start the request
[request startSynchronous];

If the request was successful, the server will redirect the request to http://www.example.com/cas/v1/tickets/{TGT}. Notice the last part of the URL is our ticket-granting ticket. To grab the ticket-granting ticket from that,

NSString *location	= [[request responseHeaders] objectForKey:@"Location"];
NSString *tgt		= [[location componentsSeparatedByString:@"/"] lastObject];

Now that we have our ticket-granting ticket, we can use it to obtain the ticket for our service (in this case, the URL to CAS on our Drupal site).

NSString *service	= @"http://drupal-site.com/?q=cas"; //The URL to the CAS module in Drupal (don't use the clean URL)

//Generate request for ticket
//https://wiki.jasig.org/display/CASUM/RESTful+API#RESTfulAPI-RequestforaServiceTicket
NSURL *url	=	[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@",server,tgt]];
request		=	[ASIHTTPRequest requestWithURL:url];

[request appendPostData:[[NSString stringWithFormat:@"service=%@",service] dataUsingEncoding:NSUTF8StringEncoding]];
[request setValidatesSecureCertificate:NO];

//Start the request
[request startSynchronous];

Now the service ticket will be the body of the response from this request.

NSString *st = [request responseString];

We have our service ticket! Hang on to this…we’ll be using this in step 3.

This code isn’t specific to iOS/Drupal communication. In fact, it can be used with any iOS application that you want to use with CAS. We’ve refined the code above and created a little CAS class for you to use in your iOS applications. All you need is the ASIHTTPRequest library.

Step 2: Connecting our iPhone App to Drupal

We’re not going into detail about connecting your iPhone app to Drupal outside of recommending the use of the Drupal/iOS SDK by Kyle Browning. This SDK provides a way to send requests to Drupal through the Services module using binary plists for fast communication. The documentation provided in the SDK and the example application are more than enough to get you started.

Step 3: Authenticating the User

We have a way to connect iOS and CAS as well as iOS and Drupal. What we’re missing is some communication between Drupal and CAS. We have the CAS module, but we need a way to pass the authentication we performed in step 1 and get a Drupal user. The Services API relies a lot on a session ID as well as user information (e.g.: the username and the user ID). Normally, we would use the user.login service to obtain this information, but the user is not a Drupal user, he/she is a CAS user. We need to create a new service that accepts a service ticket and returns the user information (similar to how the user.login service returns user information). We’ll also need to create an addition to the DiOS SDK that can communicate with our new service.

At the time of this writing, the CAS module doesn’t provide an easy way of simply reusing one of its functions to pass along a service ticket and receive an authenticated user. We had to get a little creative using the PHP cURL library. We thought this would be helpful to others in the Drupal community (especially as CAS gains popularity among universities) so we’ve submitted our module to the Drupal module repository. It’s not available for download from Drupal yet, but we attached the source code below.

The final piece to the puzzle is an additional class for the DiOS SDK. This involves subclassing the DIOSUser class (creating a DIOSCASUser class) and adding one new method:

- (NSDictionary *) loginWithServiceTicket:(NSString*)st
{
	[self setMethod:@"user.cas_login"];
	[self addParam:st forKey:@"ticket"];
	[self runMethod];
	[self setSessid:[[self.connResult objectForKey:@"#data"] objectForKey:@"sessid"]];
	[self setUserInfo:[[self.connResult objectForKey:@"#data"] objectForKey:@"user"]];
	return [self connResult];
}

This takes the response from the user.cas_login service and sets the proper properties in the DIOSConnect instance. The DIOSConnect instance now has session information for the user we logged in using CAS.

Source Code

In addition to our brief overview in this post, we’re providing all the code you need to get started implementing an iOS application with your Drupal/CAS set up.

SourceDescriptionDependencies
iOS CAS classA class to obtain a CAS service ticket with iOS.
Drupal User CAS Service moduleCreates a new service for the Services API for authenticating a user with a service ticket.
DIOSCASUser classProvides a way to connect to our new service using the DIOS SDK.

To implement the source code above, all you need to do is,

//Create connection to CAS
CAS *cas	= [[CAS alloc] initWithServer:@"https://example.com/cas/v1/tickets" withUsername:@"username" andPassword:@"pasword"];

//Get ST
NSString *st	= [cas generateServiceTicketForService:@"http://drupal-site.com/?q=cas"]; //Don't use the clean URL

//Pass service ticket to Drupal
DIOSCASUser *user = [DIOSCASUser new];
[user loginWithServiceTicket:st];

//Do whatever you want with user and CAS

//And don't forget to free up the memory
[cas release];
[user release];

And now user has all the session information for the logged in user! You can check it out by adding

NSLog(@"User: %@", user);

Of course, that needs to come before you release the user object.

We’d love to hear how you implement this code in your own applications. Let us know by adding a comment!

No related posts.


1 Comment to Connecting iOS, Drupal and CAS

  1. Thibaut's GravatarThibaut
    May 14, 2011 at 6:07 pm

    Hi,

    Thanks you for this article, it helps me to implement CAS into an iPhone app.

    However, i have a problem, obtain a TGT and a ST operate successfully but when i want to validate my ST to access to a php page, i always obtain “no” by the CAS like if the ST isn’t valid.

    I use the following code to try validation :

    NSString * theService = @”http://myWebSite.com”;

    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"https://cas.mywebsite.com/cas/validate"]];

    NSString *credentials = [NSString stringWithFormat:@"service=%@&ticket=%@",theService,st];

    [request appendPostData:[credentials dataUsingEncoding:NSUTF8StringEncoding]];
    [request setRequestMethod:@"POST"];
    [request setValidatesSecureCertificate:NO];

    [request startSynchronous];

    Someone have an idea to resolved my issue ? or can help me ? plz

    Cordially Thibaut


Leave a Reply

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

About This Blog

Float guides industry-leading companies to understand and leverage the power of mobile learning. We help companies meet their business strategies by making useful information accessible, anytime, anywhere. We are mobile learning strategy specialists.

We use our blog to share our thought leadership and provide guidance on your journey into mobile learning.

Float Mobile Learning Symposium

Register now for the Float Mobile Learning Symposium

Subscribe to our Feed

RSS
Enter your email address to subscribe to our blog via email, or click the icon on the left to subscribe in your RSS reader:

Float Newsletter

Float’s newsletter offers industry news, tips and views on the mobile learning world. Sent once a month, we promise only to send you the very best information and never sell or use your contact information to spam you.
Email:
Read our newsletter archives here.

Research Papers

In addition to our free blog and newsletter, Float has premium-quality research content available for purchase. View a list of all Float Mobile Learning research papers.

Upcoming Events

Float regularly speaks at industry events, conferences, and through webinars. We'd be very pleased for you to attend one of our sessions. Find out where you can find us next:

Free Webinar: Mobile Learning Conversations
June 13, 2012

mLearnCon 2012 Workshop: Prototyping for Mobile Learning
June 18, 2012

mLearnCon 2012: Moving Beyond ePub - Transitioning Your Content into Interactive Apps
June 19, 2012

mLearnCon 2012: Winning Over Stakeholders - How to Sell mLearning to Your Enterprise
June 20, 2012

Float Mobile Learning Symposium 2012
June 25, 2012
1871

See the full list of events.

Social Links

Float Mobile Learning Twitter Facebook Float Mobile Learning on YouTube Float Mobile Learning on Google+

Latest Tweets

Calendar of Posts

January 2011
MTWTFSS
« Dec Feb »
 12
3456789
10111213141516
17181920212223
24252627282930
31