Question

I'm working with a college and need to integrate my courses - so their students can access it on the college website. We are going with the simple iframe integration.

The user is going to register on the college website and they will pass the user information to me so I can start a session and give access to the course pages on my website which through iframe they will show on theirs.

My website is built on LAMP and I am using ZEND framework

This is a skeleton structure of how I am planning to do

1) On the college website, as part of the iframe code - they will call one of my action classes and pass the user email

<iframe src="http://mywebsite/user/validate/email/alice@gcc.com"></iframe>

2) Now in User controller - validate Action - I will basically check if user does not exist - create a new user or load an existing user with his email and start a Zend Auth instance and write the user to storage and redirect to his course page as shown below

$currentUser = $userModel->loadUserProfileByEmail($this->_getParam('email'));
$auth = Zend_Auth::getInstance();
$storage = $auth->getStorage();         
$storage->write($currentUser);
return $this->_redirect('/user/my-courses/');

This is what I have so far - and obviously it works

My Questions

1) Is this the best way to do this. I wont have the user's password because the authentication happens on college website and they dont want the user to directly login on my website.

2) This is the big question. I'm little confused about the best way to authenticate that this call is being made by this particular college. How do I go about this - do they pass a encrypted token along with this iframe call - and only I have the key to decrypt it - I've not done this - I dont know if I'm over complicating something simple.

Any advice or suggestions will be appreciated Thanks

Was it helpful?

Solution 2

I might have mis-understood your question but from what I gather you need:

-a way to authenticate a user

-the ability to pass over the page they wish to view on first-load and their email address.

The basis of this is simply symmetric key authentication - all that follows is ways to mash it up.

Put your data together (email address, Page to land on) and then hash it with a strong key.

Decrypt at other end and voila - done.

This method is secure if your password (key) is hard to guess - the following is one way that is hard to crack.

AUTHENTICATION

There are a couple of ways to do this - if you have access to their server (or someone there who can insert some code for you) then the following would work.

Create a php script that does the following.

I HAVE MASSIVELY OVER-ENGINEERED THIS TO DEMONSTRATE LOADS OF WAYS OF MAKING A HASHED STRING HARDER TO CRACK - YOU CAN CHOOSE YOUR OWN WAY!

(pseudo code)

$serverTimeStamp = timestamp;

$additionalNoise = "THEcat1sch33sy";

$time = $serverTimeStamp . "XAB"; <- needs to be a random code as delimeter.
$data =  $additionalNoise + "email@email.com";
$salt = "wh4tW0u1dB4tm4nD0?" + $serverTimeStamp;

$password then needs hashing with a reversible hash (mcrypt is a good place to start)

$encrypted = mcrypt of $data and $salt ($salt is shared key);

$authenticationcode = $time . $encrypted;

This will give you a pretty damned strong random string with a time-stamp at the front followed by XAB then a random hashed string.

This would then be passed to your user validate script.

<iframe src="http://yoursite/validate/COMPLETELYRANDOMSTRING"></iframe>

From there you reverse the process.

IMPORTANT (ammendment) - I completely forgot one IMPORTANT element - store the random string that is sent to you in a database. These strings are 'single use' - if your receive the same string again it is an attack.

This is all facilitated by the timestamp being in the salt and at the beginning of the string - can send the same data 1000 times a day with a completely different string.

Get random string.

get time-stamp from front of random string -> using regex / index of looking for numbers and then XAB (hence the random XAB string - it is just a separator)

$timeStamp = "10200192XAB";

"wh4tW0u1dB4tm4nD0?" <-shared secret key.

$salt (secret key) = "wh4tW0u1dB4tm4nD0?" + $timeStamp;

decrypt using salt

you get your data preceded by

"THEcat1sch33sy" (your additional noise) (which is also a fixed shared key in effect)

Just strip the "THEcat1sch33sy" and you have your email address (which you then validate in the 1 in a million chance that the random string actually spits out "THEcat1sch33sy" at the begninning.

Voila - not 100% but believe me - if I am trying to get into your server - I won't try this way!

PASS PAGE OVER

Simply add it to the $data - so you would pass $email + "seperator" + $coursepage.

Hope this helps (and is clear)

OTHER TIPS

Summary of my recommendations

Details
In a FSSO, there is an "Identity Provider" (IP) and a "Service Provider" (IP). The college is the Identity Provider and you are a Service Provider. There can be many service providers. Just remember IP=College, SP=you. The key points of a FSSO:

  1. Users authenticate with the IP, not the SP.
  2. When the IP signals a session is authenticated, the SP trusts it.
  3. The SP receives authenticated session signals only when a user authenticates at the IP.

According to EDUCAUSE, most colleges have a FSSO. Thus my first suggestion is to undergo a fact-finding mission to check on what the college has. Your content will be safer, your code simpler, and you will sleep better at night if they already have a FSSO. Fortunately, my experience is that colleges often have things, but knowledge of those things isn't necessarily broadcast -- you have to dig a bit.

If they don't have an FSSO, my next suggestion is to propose they install one. Educate yourself on the options, keeping in mind that Single Sign On does not imply Federated ID -- and you want both.

Personally, I recommend Shibboleth. It's open source. I've used it with LAMP and ZF1. I know it works. With Shibboleth, the college would setup a Shibboleth IP, you would setup your SP, together you'd participate in the data flow of identity, and once a user logs in you'd receive environment variables on each connection signaling authentication like this:

array (
    // ...
    [Shib-Application-ID] => my_course_catalog
    [Shib-Session-ID] => _6c45a07c8bc73190242212124221b7
    [Shib-Identity-Provider] => https://shib.college.edu/idp/shibboleth
    [Shib-Authentication-Instant] => 2013-12-31T22:42:07.101Z
    [Shib-AuthnContext-Decl] => urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
    [affiliation] => member@college.edu;staff@college.edu
    [eppn] => XXXXXX@college.edu
    [unscoped-affiliation] => member;staff
    // ...
    [REMOTE_USER] => XXXXXX@college.edu
    // ...
)

The way I implemented this in ZF1 was a controller plugin to look for Shib-Session-ID. If found, manufacture a Shibboleth resource and populate with the Shib-Session-ID and the REMOTE_USER, which I could later interrogate for everything I needed. If not found, redirect to the IP login page. (Since you are in an IFRAME, don't do this: instead redirect to a "no content to display"/"default content" action.)

What if they won't accept a proposal of installing a FSSO? Then you have to roll your own and the sticking point for you will be, as you noted, trust.

The problem with them sending you a token (your #2 question) is that token can be intercepted (with varying degrees of ease) and replayed against you. You cannot trust what you are given. You have to take what you are given and ask a source you trust to verify what's given.

The even bigger problem is that you need to know if the user browsing the web page right now is the same user who was and still is logged in. For that you need the login cookie the college issued, and you need to check that cookie is currently valid.

There is no easy way to do it securely. That's why FSSO were invented, so all that heavy lifting can be done once in a provably secure manner. If you still have roll your own, the best model I can offer is that of a Facebook app. The kind where the "app" running on a third-party server "sees" the logged in Facebook user. To get you started, here's the Facebook tutorial on app authentication.

(The way app authentication is currently done is an IFRAME POST with the login session ID, which you check back with Facebook... but I understand browser's are no longer allowing this and you have to get around it. I don't know for sure, something to keep in mind.)

In the long run, an FSSO is an asset for the college and a boon for you. Go with that if at all possible. Otherwise, the state-of-the-art for IFRAME third-party app with authentication is the Facebook-to-Facebook app exchange, so model that. Good luck!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top