Search This Blog

Saturday, April 10, 2010

Hack #1 a.k.a. The Poor Man's Single Sign On (SSO) - Part 3 - The Finish

Here's how I did it.

First, we make a list of the clients who should have access to the learning site.  When these clients browse to website A, we set a cookie with a secret value in it.  For this I used a randomly generated 32 character string.

For example, let's say client IndyZoo needs access to specialized training materials.  We assign this account a cookie that will be set whenever they log into website A.  In this case the secret value of the cookie is "12ksH9stglasidfj019832urjjdnasfv".

Second, we enable website B to read cookies set by website A.  On website A (www.mysite.com) we set the cookie with a pre-arranged value based on the client's name.  This cookie's domain is important.  By setting it to use the domain of "mysite.com" we enable the second website (B learning.mysite.com) to read the value stored in the cookie.

For example, here is php code that sets the cookie for IndyZoo.
// Set a cookie
// Cookie name: id
// Cookie value: 12ksH9stglasidfj019832urjjdnasfv
// Cookie expire: in 1 day
setcookie ('id', '12ksH9stglasidfj019832urjjdnasfv', time() +86400 ,'/','.mysite.com');
?>


Third, we use apache's mod_rewrite to check the value of the cookies, along with protecting the content of the website path.  In this example we want to redirect web browsers that do not have our secret cookie value for IndyZoo clients.  We simply route them back to website A for a chance to log in again.  This keeps people from viewing the material that are for IndyZoo eyes only.

Please note that I have not worked with IndyZoo - just think it's a great place to visit.  They have no affiliation and can have their name taken out of the blog post if they would like.  Either way, keep up the great work with the Zoo.  I just needed a nice fictional company to work for in this example.

The Apache config file on website B would need the following entries:

RewriteEngine On
RewriteCond
RewriteRule

For this hack I have included the explanation of the entries as part of the configuration:

Listen 1.2.3.4:80

       ServerName learning.mysite.com
       ServerAdmin webmaster@mysite.com

       # If RewriteEngine is not on, or you don't have the mod_rewrite module installed or enabled, this won't work!
         RewriteEngine On
        # By setting a mod_rewrite log we can more easily debug problems by reviewing the logs
       RewriteLog /usr/local/apache2/logs/rewrite.log
       RewriteLogLevel 3

       ################## Important #######################################
       # NOTE: the way mod_rewrite with RewriteConditions works is this:
       # Step 1: did we match on the pattern in RewriteRule?
       # Yes --> try to mach on RewriteCond, if yes, continue with the subsitution in the RewriteRule, else look for next rule
       # No  --> stop processing this rule block and look for next rule
       ####################################################################

       # no cookie already set? we handle this situation by setting a cookie with a value that keeps them out
       RewriteCond  %{HTTP_COOKIE} !^.*id.*$ [NC]
       RewriteRule  ^(.*)$|.*  http://learning.mysite.com [R,L,cookie=id:unknown:.mysite.com:86400:/]

   
        # Do they NOT have one of the acceptable cookies?  If they do not, redirect.  Otherwise continue with other checks...
        # NC means this is a case-insensitive match
        # L means it is the last rule to apply if a match is found
         # R means it is a redirect
       RewriteCond %{HTTP_COOKIE} !^.*id=12ksH9stglasidfj019832urjjdnasfv|asdrfrwqre28mlsfdiuj098i23mn5t8j
       RewriteRule ^(.*)$|.*  http://www.mysite.com [L,R]

        # Don't have the IndyZoo cookie but trying to get to it's resources?  Redirect them!
       RewriteCond %{HTTP_COOKIE} !^.*id=12ksH9stglasidfj019832urjjdnasfv[NC]
       RewriteRule ^/IndyZoo(.*)$  http://www.mysite.com [L,R]

        # Don't have the generic cookie but trying to get to it's resources?  Redirect them!   
       RewriteCond %{HTTP_COOKIE} !^.*id=asdrfrwqre28mlsfdiuj098i23mn5t8j [NC]
       RewriteRule ^/generic(.*)$  http://www.mysite.com [L,R]

         # what if they have a valid cookie, but are snooping around trying different paths we did not name specifically? Redirect them!
       # trying to get a resource we did not send the user to from www.mysite.com ..., time to redirect them!
       RewriteRule !^/[(IndyZoo|generic)](.*)$  http://www.mysite.com [L,R]


       #Mappings cookie is "id:value" to client  --> eg IndyZoo, generic
       #IndyZoo : 12ksH9stglasidfj019832urjjdnasfv
       #generic : asdrfrwqre28mlsfdiuj098i23mn5t8j

       DocumentRoot /var/www/learning/htdocs/
      
      


Links that made this possible:

Official mod_rewrite info - very tech oriented
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html

Examples of how to use mod_rewrite
http://www.yourhtmlsource.com/sitemanagement/urlrewriting.html

Site with very nice examples
http://www.askapache.com/htaccess/htaccess-fresh.html

I hope you find this helpful.  While researching how to accomplish this it was difficult to find solid examples that don't use server-side languages to check cookie values.  That is why I wrote this.  Pass it on to the next guy sweating a deadline.  Or, keep it in your back pocket for a rainy day.

Saturday, April 3, 2010

Hack #1 a.k.a. The Poor Man's Single Sign On (SSO) - Part 2

Most of you will immediately think of setting / checking cookie values using the base domain name  (mysite.com in this example).  And, that is part of the solution.  However, there is not a server-side scripting language available on web-server b. 

You might say "but, can't we just ....[insert something to the effect of recreating the web-server b content / layout & etc. entirely and use language X to check the cookie values]?"  Technically we can.  But as is often the case, the answer from management is a resounding "no".  That would take too long and cause other problems challenges.

Earlier I hinted at using Apache's mod_rewrite to meet the requirements.  Today's hint is the following:
RewriteCond and RewriteRule

Things might seem obvious now.  But there's a twist coming.  And, it was relatively difficult to figure out.

Wednesday, March 31, 2010

Hack #1 a.k.a. The Poor Man's Single Sign On (SSO)

I'm a technical consultant - think Web technology.  A few days ago a client of mine asked me to enable users who had already logged onto web-server A to be able to access certain "protected" content on web-server B.  The two websites share a common domain name.  For example:  website A's name is www.mysite.com and website B's name is learning.mysite.com. 

Did I mention that website B could only support HTML? 

I'll share my solution over the next couple posts.  For now, the hint is mod_rewrite.