How To Enable Single Sign-On Using the Tin Can iOS SDK

Code Snippets For You To Implement the iOS SDK with Your Tin Can Project

Experience API, Mobile Development Comments (0)

I got an email the other day asking for some thoughts on designing a single sign-on (SSO) user experience with Float’s Tin Can iOS SDK. Great question.

The Tin Can API specification allows for two different methods of authentication with the LRS: Basic authentication and oAuth (version 1). If you’re using Wax LRS or SCORM Cloud, both use basic authentication to identify the application posting statements to the LRS. (Wax LRS also currently supports the registered application, unknown user oAuth scenario.) In this model, the iOS application is completely trusted by the LRS. The LRS doesn’t authenticate the person using the application – it only verifies that the application is using the right keys. It is up to your application to determine who the user is (and whether they are allowed to be posting statements to the LRS).

The simple answer is: you can implement a single sign-on solution however you want. Because the job of authentication is up to your app, you pass along any user information you want to the LRS.

So, where can you get this user information from?

In iOS 5, users could enter their Twitter credentials once into their system settings, and other apps (with the user’s permission) could use that token to make requests to Twitter and learn about the user. In iOS 6, the same became possible with Facebook. We can use this to create a SSO experience within any iOS application.

// Retrieve the user information
ACAccountStore *accountStore = [ACAccountStore new];
// Request access to the user's Twitter accounts
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error){

// If the user allowed access (or previously allowed access), "granted" will be YES
if (granted)
{
// Fetch the accounts previously requested (remember, we're only requesting Twitter accounts)
NSArray *accounts = [accountStore accountsWithAccountType:accountType];

if (accounts.count>0)
{
// It's important to note that a user may have more than one Twitter account
// It's up to you to create an interface that allows the user to choose which Twitter account he/she wants to use
// In this example, we'll just use the first one.
ACAccount *twitterAccount = [accounts objectAtIndex:0];

// Create an agent object
TCAgent *agent = [TCAgent agentWithName:nil andMbox:nil];
TCAccount *account = [TCAccount accountWithID:twitterAccount.username forHomePage:@"http://twitter.com"];

agent.account = account;

// Do something with the agent object...
}
}
}];

iOS will only return the username for the requested service (whether it be Twitter or Facebook). Since Tin Can requires exactly one piece of identifying information, the username for a specific service is all you need.

If you want to add the full name, you’ll need to ask Twitter or Facebook for that.

// Create a request to the social network service (in this case, Twitter)
// In iOS 5, you'll need to use TWRequest
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:@"https://api.twitter.com/1.1/account/verify_credentials.json"] parameters:nil];

// Specify the account
request.account = twitterAccount;

[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error){
// TODO: Handle errors
// Twitter responds with JSON, so using the JSON deserialization functions in iOS 5+,
// we can get an NSDictionary object from the response
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];

// Set the agent's name
agent.name = [response objectForKey:@"name"];
}];

Now you have a fully-formed TCAgent object that can be used for creating statements and persisting them to the LRS.

The Tin Can SDK can even “remember” the default actor:

[TCAPI defaultAPI].defaultActor = agent;

Unless otherwise specified, statements sent through the statement queue to the LRS will automatically have this actor assigned. You can also reference this value anywhere you want.

What about a custom single sign-on solution using your enterprise’s AD or CAS services? Remember, you get to specify the user information before sending statements to the LRS. In order to obtain the user information, you’ll need to handle the authentication of the user yourself (there will likely be some open-source solutions for you to use). The tricky part will be figuring out how to share an authenticated session or token across apps. For the most part, apps are completely sandboxed and can’t access data from other apps (including documents, cookies, etc). However, there are a few ways to pass data back and forth. I recommend using the iOS Keychain Services. The iOS Keychain allows you to share data (specifically, authentication data) across multiple apps with the same identifier prefix.

Try Tin Can out for free in your organization by selecting the button below!







Follow Float
The following two tabs change content below.

» Experience API, Mobile Development » How To Enable Single Sign-On...
On January 7, 2013
By
, ,

Leave a Reply

Your email address will not be published. Required fields are marked *

« »