You would like to use the Single Sign On (SSO) feature in Google Apps in your PHP application?
According to Google you are advised to use simplesamlphp.
In my opinion simpleSAMLphp has grown to a full suite of SAML modules and the amount of code and possibilities to configure things make it more complex than simple. (There is good documentation though, so its not too hard to really get a single installation up and running [given you have the right server, php mods and access rights on your hosting machine]).
I did not need the various modules supplied with simpleSAMLphp – i looked for a straight way to create the SAMLResponse for Google Apps to act as Identity Provider (IdP) – nothing more and nothing less.
In addition to that simpleSAMLphp was no real option for me as i did not want to put ~1000 files of code into my application – i wanted a very small part of code that i can easily review and check and then embed in my own application.
So i started to read documentation, support forums etc. etc. and although my XML looked good – Google Apps “was not able to parse the login”. Reading the google SAMLsupport forum did not really help either as the current message of the day is: “Use simpleSAMLphp!”.
So i ended up with installing simplesamlphp anyway, because it seemed the only way to get an accepted XML request to check against (the templates you find in the google docs are all outdated).
If you are in a similar position my advice is to use an online xml compare tool and check all differences you find against a known valid SAMLresponse.
There are so many small caveats you can run into that it’s hard to list them all. A quick checklist would something like this:
- Do you have the assertion signed? (Signing the response is optional, skip it if you trace errors)
- Does your ID attribute start with a letter? (not a number)
- Make sure your namespaces and attributes are right (i ended up with “Id” and “ID” attributes simultanously at one point when working with the xmlseclibs)
- Is your key formatted the way your signature code/library needs it? [e.g. RSA-SHA1 in PEM format]
Long story short – i have successfully created a simple php script which is able to create a SAMLresponse accepted by google apps:
SAMLResponse PHP Script to use as IdP for Google Apps
Here is the code, plain and simple for you to copy, learn and use as you wish. As usual: no warranty, no obligation, no fee – just a free code sample:
contains the xmlseclibs for you convenience.
Make sure you insert the private and public keys. You can generate them as described in the simpleSAML tutorial:
openssl genrsa -des3 -out googleappsidp.key 1024 openssl rsa -in googleappsidp.key -out googleappsidp.pem openssl req -new -key googleappsidp.key -out googleappsidp.csr openssl x509 -req -days 9999 -in googleappsidp.csr -signkey googleappsidp.key -out googleappsidp.crt
You’ll find the blocks for public and private certs in the response_params:
$response_params['x509'] = <<<X509 -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- X509; $private_key = <<<RSA_PRIVATE_KEY -----BEGIN RSA PRIVATE KEY----- [...] -----END RSA PRIVATE KEY----- RSA_PRIVATE_KEY;
Example
//Somewhere in your code...
//Determine which user wants to login (check session.. have a login screen whatever - remember the 2 vars RelayState + SAMLRequest though)
$loginUser = 'john@my-google-domain.com';//John it is.. good
//Prepare the SAMLResponse and use HTTP-POST Binding to send the user to google apps.
$auth = new xauth_googleapps();
$auth->login($_GET['SAMLRequest'],$loginUser);
//This script is for demonstration purposes - the block below is a XSS vulnerability for sure, so make sure your code handles the GET vars with some respect ^^
$form = <<<FORM
<h3>Redirecting you to Google</h3>
<form action="{$auth->acs_url}" method="post"><input type="hidden" name="RelayState" value="{$_GET['RelayState']}" />
<input type="hidden" name="SAMLResponse" value="{$auth->SAML_response}" />
<input type="submit" value="Submit" /></form><script type="text/javascript">// <![CDATA[
document.forms[0].submit();
// ]]></script>
FORM;
print $form;
Enjoy!
Google+