Here is another PHP Preauth example (requires PHP >= 5.1.2 compiled with hash support).
Configuration for single or multiple domain support:
PHP Code:
// Configuration array allowing different settings per domain
$_zimbra_preauth = array(
"" => array(
// Configurable qstring, {account} replaced by $account etc...
"qstring" => "account={account}&by={by}&timestamp={timestamp}&expires={expires}&preauth={preauth}",
// preauthkey for the given domain
"preauthkey" => "6b7ead4bd425836e8cf0079cd6c1a05acc127acd07c8ee4b61023e19250e929c",
// This domain has a redirectURL
"qstring" => "account={account}&by={by}&timestamp={timestamp}&expires={expires}&preauth={preauth}&redirectURL=/zimbra/h/",
"preauthkey" => "6b7ead4bd425836e8cf0079cd6c1a05acc127acd07c8ee4b61023e19250e929c",
Function to generate the preauth and qstring:
PHP Code:
// Generate the preauth qstring for the user and optional domain
function Zimbra_gen_preauth_qstring($user,$domain="") {
    if (!isset(
$domain) || ($domain == "")) { $domain ""; }
// Copy the qstring template localy to operate on it
$out $_zimbra_preauth[$domain]['qstring'];
// Setup the default pieces except for the preauth
$parts = array(
// Create the preauth hash and add it to the parts
$parts['preauth'] = hash_hmac('sha1',join("|",$parts),$_zimbra_preauth[$domain]['preauthkey']);
// Go through the parts and replace each qstring template parameter with the appropriate one
foreach ($parts as $part=>$val) {
$out str_replace("{{$part}}",urlencode($val),$out);
// Return the filled qstring to be added to
return $out;

Example Usage:
PHP Code:
// Example usage for
$qstring Zimbra_gen_preauth_qstring("myuser");
// Or if the domain is not the default domain
// $qstring = Zimbra_gen_preauth_qstring("myuser","");
  • You will want to add error checking so that gen requests for undefined domains error out elegantly
  • You will likely want to gently rework the code for your application as the comments and variables are named more for illustration than convention.
  • You can move the config array into the function and simplify the whole thing if you do not want a globally sourced variable or do need the ability to configure multiple domains.
  • If you already have a Zimbra related class you can simply add it into your class and call it accordingly.