<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Utahcon.com &#187; Single Signon</title>
	<atom:link href="http://blog.utahcon.com/tag/single-signon/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.utahcon.com</link>
	<description></description>
	<lastBuildDate>Wed, 25 Jan 2012 14:18:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PHP and Josso &#8211; Transparency Rocks!</title>
		<link>http://blog.utahcon.com/computers/code/php-and-josso-transparency-rocks?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php-and-josso-transparency-rocks</link>
		<comments>http://blog.utahcon.com/computers/code/php-and-josso-transparency-rocks#comments</comments>
		<pubDate>Wed, 20 Jan 2010 22:15:38 +0000</pubDate>
		<dc:creator>utahcon</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Josso]]></category>
		<category><![CDATA[planet]]></category>
		<category><![CDATA[Single Signon]]></category>

		<guid isPermaLink="false">http://blog.utahcon.com/?p=315</guid>
		<description><![CDATA[Bogdan recently asked in my comments: I can&#8217;t seem to find a call like josso_authenticate($name, $pass), returning an array to be appended to user&#8217;s SESSION. I was expecting such a method, because SOAP is already used everywhere, so it shouldn&#8217;t be too hard implementing this. Has anyone had success implementing this kind of &#8220;transparent&#8221; login? [...]]]></description>
			<content:encoded><![CDATA[<p>Bogdan recently asked in my comments:</p>
<blockquote><p>I can&#8217;t seem to find a call like josso_authenticate($name, $pass), returning an array to be appended to user&#8217;s SESSION. I was expecting such a method, because SOAP is already used everywhere, so it shouldn&#8217;t be too hard implementing this.</p>
<p>Has anyone had success implementing this kind of &#8220;transparent&#8221; login?</p></blockquote>
<p>JOSSO simply doesn&#8217;t make it easy to log people in with a single call. Instead you need to make an interface to the API to do so. I just so happen to have an example of such a wrapper function.</p>
<p><span id="more-315"></span></p>
<h2>Logging In A User</h2>
<p>To do everything and make it easy for future reuse I built two classes. The first is a Login Class and the second a Josso Class (below). My Login Class is pretty sparse, but it includes a wrapper to handle all the tasks required to login a user through Josso and get back the Josso details for that user.</p>
<p>The full code of each class is down at the bottom of the post, just expand the code block, but here is the function that is really what you are looking for Login-&gt;authorize()</p>
<h2>Login-&gt;authorize()</h2>
<pre class="brush: php; title: ; notranslate">public function authorize($username, $password){

 # make sure we have a valid username
 if(empty($username)){
 # return invalid username
 throw new LoginException('Invalid username');
 } else {
 $this-&gt;username = $username;
 }

 # make sure we have a valid password
 if(empty($password)){
 # return invalid username
 throw new LoginException('Invalid password');
 }

 # check that user exists
 if( ! $this-&gt;josso-&gt;userExists($this-&gt;username)){
 throw new LoginException('Invalid username');
 }

 # check Josso with username and password
 $this-&gt;assertion = $this-&gt;josso-&gt;assertIdentityWithSimpleAuthentication($username, $password);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Invalid username/password combination');
 }

 # resolve Authentication Assertion
 $this-&gt;token = $this-&gt;josso-&gt;resolveAuthenticationAssertion($this-&gt;assertion);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Interal Error [Login]: '. __LINE__);
 }

 $this-&gt;session = $this-&gt;josso-&gt;getSession($this-&gt;token);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Interal Error [Login]: '. __LINE__);
 }

 $this-&gt;user = $this-&gt;josso-&gt;findUserInSession($this-&gt;token);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Interal Error [Login]: '. __LINE__);
 }

 $this-&gt;cleanUpUser();

 $this-&gt;roles = $this-&gt;josso-&gt;findRolesByUsername($this-&gt;username);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Interal Error [Login]: '. __LINE__);
 }

 $this-&gt;cleanUpRoles();

 $this-&gt;user-&gt;sosPermissions =&amp; $this-&gt;roles;
 }</pre>
<h2>What That Actually Did</h2>
<p>As you can see you simply pass the $username and $password to the function and it runs through a ton of work for you.</p>
<p>First it validates the input, make sure you aren&#8217;t working for no reason.</p>
<p>Next it makes sure the <strong><em>userExists()</em></strong>, this will save you heartache later when JOSSO pretends a user exists, but really doesn&#8217;t.</p>
<p>Then I <strong><em>asserIdentityWithSimpleAuthentication()</em></strong> which literally means I pass those to JOSSO and wait for an answer. The answer returned is an <strong>assertion_id</strong>, which really doesn&#8217;t mean anything.</p>
<p>You then take the <strong>assertion_id</strong> returned and call <strong><em>resolveAuthenticationAssertion()</em></strong>, this will return your <strong>session_id</strong> if the login was valid.</p>
<p>With the <strong>session_id</strong> you call <em><strong>getSession()</strong></em>. This returns all the details of the session that JOSSO now has open. This varies depending on who setup your JOSSO implementation but you should have an identifying is (user_id) if nothing else.</p>
<p>I go on to make sure that JOSSO hasn&#8217;t forgotten anything by calling <em><strong>findUserInSession()</strong></em>, which literally just tells me who I am supposed to be working with.</p>
<p>The <em><strong>cleanUpUser()</strong></em> you could probably ignore, but our system returns an object with dots ( . ) in the name and I can&#8217;t stand that, so I change them to underscores ( _ ).</p>
<p>Finally I call back to my JOSSO install to get any roles the user has, again this will vary if your JOSSO doesn&#8217;t handle roles.</p>
<h2>Login Class</h2>
<pre class="brush: php; collapse: true; light: false; title: ; toolbar: true; notranslate">

class Login {

 public $token;
 public $username;
 public $session;
 public $roles;
 public $user;
 public $request;
 private $assertion;
 # this will hold the instance of Josso Controller we need
 private $josso;

 function Login($request = null){

 $this-&gt;josso = new Josso;
 if(!empty($request)){
 $this-&gt;request = $request;
 }
 }

 #validate an existing token
 public function validateToken($user_token){
 $session = $this-&gt;josso-&gt;accessSession($user_token);

 /*
 * For whatever reason Josso returns nothing if the session is valid
 * and the operation has been completed.
 */
 if( empty($session)){
 return true;
 }

 if($this-&gt;josso-&gt;error){
 throw new LoginException('Internal Error [Login]: '. __LINE__);
 }
 return false;
 }

 # authorize a user with password
 public function authorize($username, $password){

 # make sure we have a valid username
 if(empty($username)){
 # return invalid username
 throw new LoginException('Invalid username');
 } else {
 $this-&gt;username = $username;
 }

 # make sure we have a valid password
 if(empty($password)){
 # return invalid username
 throw new LoginException('Invalid password');
 }

 # check that user exists
 if( ! $this-&gt;josso-&gt;userExists($this-&gt;username)){
 throw new LoginException('Invalid username');
 }

 # check Josso with username and password
 $this-&gt;assertion = $this-&gt;josso-&gt;assertIdentityWithSimpleAuthentication($username, $password);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Invalid username/password combination');
 }

 # resolve Authentication Assertion
 $this-&gt;token = $this-&gt;josso-&gt;resolveAuthenticationAssertion($this-&gt;assertion);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Interal Error [Login]: '. __LINE__);
 }

 $this-&gt;session = $this-&gt;josso-&gt;getSession($this-&gt;token);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Interal Error [Login]: '. __LINE__);
 }

 $this-&gt;user = $this-&gt;josso-&gt;findUserInSession($this-&gt;token);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Interal Error [Login]: '. __LINE__);
 }

 $this-&gt;cleanUpUser();

 $this-&gt;roles = $this-&gt;josso-&gt;findRolesByUsername($this-&gt;username);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Interal Error [Login]: '. __LINE__);
 }

 $this-&gt;cleanUpRoles();

 $this-&gt;user-&gt;sosPermissions =&amp; $this-&gt;roles;
 }

 public function createLoginFromToken($token){

 $this-&gt;user = $this-&gt;josso-&gt;findUserInSession($token);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Interal Error [Login]: '. __LINE__);
 }

 $this-&gt;cleanUpUser();

 $this-&gt;roles = $this-&gt;josso-&gt;findRolesByUsername($this-&gt;user-&gt;name);
 if($this-&gt;josso-&gt;error){
 throw new LoginException('Interal Error [Login]: '. __LINE__);
 }

 $this-&gt;cleanUpRoles();

 $this-&gt;user-&gt;sosPermissions =&amp; $this-&gt;roles;
 }

 # get a Josso hashed version of a password
 public function getPassHash($password){
 $passhash = $this-&gt;josso-&gt;getPassHash($password);
 return $passhash;
 }

 # acquire roles for the user from josso
 public function getUserRoles(){
 return $this-&gt;roles;
 }

 # send the signal to Josso to signoff (closes all sessions)
 public function signoff($session_id = null){
 if( ! $session_id &amp;&amp; ! $this-&gt;session-&gt;id){
 return false;
 }

 if(!$session_id){
 if(!empty($this-&gt;session)){
 if($this-&gt;josso-&gt;globalSignoff($this-&gt;session-&gt;id)){
 return true;
 }
 } else {
 return false;
 }
 } else {
 if($this-&gt;josso-&gt;globalSignoff($session_id)){
 return true;
 }
 }
 return false;
 }

 private function cleanUpUser(){
 if(!empty($this-&gt;user)){
 foreach($this-&gt;user-&gt;properties as $prop =&gt; $details){
 $name = $details-&gt;name;
 if($pos = strpos($name, '.')){
 $name = explode('.',$name);
 $name = $name[0] . ucwords($name[1]);
 }
 $this-&gt;user-&gt;$name = $details-&gt;value;
 }
 unset($this-&gt;user-&gt;properties);
 }
 }

 private function cleanUpRoles(){
 if(!empty($this-&gt;roles)){
 foreach($this-&gt;roles as $key =&gt; $details){
 $tmpRoles[$key] = $details-&gt;name;
 }
 $this-&gt;roles = $tmpRoles;
 }
 }
}
?&gt;</pre>
<h2>Josso Class</h2>
<pre class="brush: php; collapse: true; light: false; title: ; toolbar: true; notranslate">
&lt;pre&gt;class Josso {

 var $SSOIdentityManager;
 var $SSOSessionManager;
 var $SSOIdentityProvider;
 var $JossoPashHash;
 var $error;

 function Josso(){

 // create the soapclients
 $this-&gt;SSOIdentityManager = new Soapclient(JOSSO_SERVER .'/josso/services/SSOIdentityManager?wsdl', array('Trace' =&gt; 1));
 $this-&gt;SSOSessionManager = new Soapclient(JOSSO_SERVER .'/josso/services/SSOSessionManager?wsdl', array('trace' =&gt; 1));
 $this-&gt;SSOIdentityProvider = new Soapclient(JOSSO_SERVER .'/josso/services/SSOIdentityProvider?wsdl', array('trace' =&gt; 1));
 }

 function accessSession($session_id){
 try{
 $accessSession = $this-&gt;SSOSessionManager-&gt;accessSession($session_id);
 // we expect a null
 return $accessSession;
 } catch(Exception $e){
 $this-&gt;error = $e;
 return false;
 }
 }

 // check if a user exists
 function userExists($username){
 try {
 $userExists = $this-&gt;SSOIdentityManager-&gt;userExists($username);
 return true;
 } catch (Exception $e){
 $this-&gt;error = $e;
 return false;
 }
 }

 // assert a login
 function assertIdentityWithSimpleAuthentication($username, $password){
 try{
 $loginAssertion = $this-&gt;SSOIdentityProvider-&gt;assertIdentityWithSimpleAuthentication($username, $password);
 return $loginAssertion;
 } catch (Exception $e){
 $this-&gt;error = $e;
 return false;
 }
 }

 // check assertion and get session
 function resolveAuthenticationAssertion($loginAssertion){
 try{
 $session = $this-&gt;SSOIdentityProvider-&gt;resolveAuthenticationAssertion($loginAssertion);
 return $session;
 } catch (Exception $e){
 $this-&gt;error = $e;
 return false;
 }
 }

 // get session details
 function getSession($session){
 try {
 $sessionDetails = $this-&gt;SSOSessionManager-&gt;getSession($session);
 return $sessionDetails;
 } catch (Exception $e){
 $this-&gt;error = $e;
 return false;
 }
 }

 // make sure the session we found belongs to our user
 function findUserInSession($session){
 try {
 $userInSession = $this-&gt;SSOIdentityManager-&gt;findUserInSession($session);
 return $userInSession;
 } catch (Exception $e){
 return false;
 }
 }

 // not used
 function findUser($username){
 try{
 $userDetails = $this-&gt;SSOIdentityManager-&gt;findUser($username);
 return $userDetails;
 } catch (Exception $e){
 return $e;
 }
 }

 // get a users roles
 function findRolesByUsername($username){
 try {
 $userRoles = $this-&gt;SSOIdentityManager-&gt;findRolesByUsername($username);
 return $userRoles;
 } catch (Exception $e){
 $this-&gt;error = $e;
 return false;
 }
 }

 function globalSignoff($session){
 try {
 $signoff = $this-&gt;SSOIdentityProvider-&gt;globalSignoff($session);
 } catch (Exception $e){
 $signoff = $e;
 }
 unset($_SESSION['josso']);
 return $signoff;
 }

 function getPassHash($password){
 try{
 $result = $this-&gt;JossoPashHash-&gt;hash($password);
 return $result;
 } catch (Exception $e){
 return $e;
 }
 }

}</pre>
<h2>That&#8217;s It!</h2>
<pre>I hope I have at least in part helped with your quest to make logging people in through JOSSO more bearable.</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.utahcon.com/computers/code/php-and-josso-transparency-rocks/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

