<?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>Extensible Development &#187; authentication</title>
	<atom:link href="http://blog.itwarlocks.com/tag/authentication/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.itwarlocks.com</link>
	<description>Profession blog about Software Engineering, Web, *nix, Processes, Tools and more.</description>
	<lastBuildDate>Mon, 29 Mar 2010 12:20:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PHP based authentication for mod_dav</title>
		<link>http://blog.itwarlocks.com/2009/04/27/php-based-authentication-for-mod_dav/</link>
		<comments>http://blog.itwarlocks.com/2009/04/27/php-based-authentication-for-mod_dav/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 12:24:41 +0000</pubDate>
		<dc:creator><span property="dc:creator" resource="http://blog.itwarlocks.com/2009/04/27/php-based-authentication-for-mod_dav/">Jeffrey Ridout</span></dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[mod_auth]]></category>
		<category><![CDATA[mod_auth_script]]></category>
		<category><![CDATA[mod_dav]]></category>
		<category><![CDATA[mod_dav_fs]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[WebDAV]]></category>

		<guid isPermaLink="false">http://blog.itwarlocks.com/?p=43</guid>
		<description><![CDATA[To be able to create a Document Management System in Word using WebDAV on Apache webserver, I did some research on mod_dav, an Apache module to provide WebDAV support. It appears that the authaurisation part of mod_dav is limited to "allow all" / "deny all", which did not quite suite my needs. The solution needed more fine-grained authorisation on a per-directory level. Another problem was that the authentication and authorisation data was in a database.]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>To be able to create a <a href="http://blog.itwarlocks.com/2009/04/24/document-management-system-in-word-using-webdav/" target="_self">Document Management System in Word using WebDAV</a> on <a title="Apache webserver official website." href="http://httpd.apache.org/" target="_blank">Apache webserver</a>, I did some research on <a title="Mod_dav's official website." href="http://www.webdav.org/mod_dav/" target="_blank">mod_dav</a>, an Apache <a title="Official Apache webserver module registry." href="http://modules.apache.org/" target="_blank">module</a> to provide <a id="aptureLink_vPPLLegkod" title="Information on WebDAV on Wikipedia.org" href="http://en.wikipedia.org/wiki/WebDAV">WebDAV</a> support. It appears that the authaurisation part of mod_dav is limited to &#8220;allow all&#8221; / &#8220;deny all&#8221;, which did not quite suite my needs. The solution needed more fine-grained authorisation on a per-directory level. Another problem was that the authentication and authorisation data was in a database.<span id="more-43"></span></p>
<h3>Issues</h3>
<ol>
<li>Mod_dav does not have a fine-grained authorisation system on a per-directory level.</li>
<li>Directory structure is known but unstable.</li>
<li>Authorisation data is held in a database and requires complex SQL.</li>
</ol>
<h3>Solution</h3>
<h4>Fine-grained authorisation</h4>
<p>I started by looking at <a title="Mod_auth's official website." href="http://httpd.apache.org/docs/2.0/mod/mod_auth.html" target="_blank">mod_auth</a> and <a title="Mod_auth_dbd's official website." href="http://httpd.apache.org/docs/2.2/mod/mod_authn_dbd.html" target="_blank">mod_auth_dbd</a> (in combination with <a title="Mod_dbd's official website." href="http://httpd.apache.org/docs/2.2/mod/mod_dbd.html" target="_blank">mod_dbd</a>), but the SQL useable by mod_dbd only received the username and password as parameters, not the requested <a id="aptureLink_c3qbx5wU5Q" title="Information on URI on Wikipedia.org" href="http://en.wikipedia.org/wiki/Uniform%20Resource%20Identifier">URI</a>. What mod_auth module could possibly be used? The solution to this was quite unexpected: <a title="Mod_auth_script's official website." href="http://mod-auth-script.sourceforge.net/" target="_blank">mod_auth_script</a>.</p>
<p>Mod_auth_script allows CGI or <a title="PHP's official website." href="http://www.php.net" target="_blank">PHP</a> scripts to handle the authorisation. By looking at the <a title="PHP.net official documentation on $_SERVER predefined variables." href="http://www.php.net/manual/en/reserved.variables.server.php" target="_blank">REQUEST_URI</a> the script can easily decide to simulate authorisation by invalidating the authorisation.</p>
<p>I created a PHP script that at first would log the REQUEST_URI and allow access for any username and password. All that is left now is to handle authorisation based on the directory structure and fetch the real authorisation from the database.</p>
<div>
<div class="wp-caption" style="text-align: left">Listing 1: Apache config</div>
<pre class="brush: xml">
&lt;Location /dav&gt;
	Options			+Indexes
	Dav				On
	AuthType		Basic
	AuthName		&quot;PHP based authentication for mod_dav&quot;
	AuthScriptFile	/any_full_path_your_apache_can_get_to/.auth.php
	Require			valid-user
&lt;/Location&gt;
</pre>
</div>
<div>
<div class="wp-caption" style="text-align: left">Listing 2: .auth.php (version 0.0.1)</div>
<pre class="brush: php">
&lt;?php
/**
 * PHP based authentication for mod_dav
 * @author Jeffrey Ridout
 * @link http://blog.itwarlocks.com
 * @license http://creativecommons.org/licenses/by-sa/3.0
 * @date 2009-04-27
 * @version 0.0.1
 */

/**
 * $_SERVER[&#039;REQUEST_URI&#039;] contains the location accessed by the WebDAV client.
 * Using parse_url enables easy access to all URL parts.
 */
$requestURI = parse_url($_SERVER[&#039;REQUEST_URI&#039;]);

/**
 * Accessing some pages directly, like a page containing phpinfo(), will result in several
 * calls to .auth.php. These do not need to be logged.
 */
if ($requestURI[&#039;path&#039;] != $_SERVER[&#039;SCRIPT_NAME&#039;]) {
	$logFile = fopen(&#039;auth.log&#039;, &#039;a&#039;);
	fwrite($logFile, &quot;${_SERVER[&#039;PHP_AUTH_USER&#039;]}:${_SERVER[&#039;PHP_AUTH_PW&#039;]}@${requestURI[&#039;path&#039;]}\n&quot;);
	fclose($logFile);
}

/**
 * At this stage we always allow access.
 * mod_auth_script catches custom headers to define the result to mod_auth.
 * auth-script:allow|deny|prompt Defines the authentication result.
 */
header(&#039;auth-script:allow&#039;);

/* EOF */
?&gt;
</pre>
</div>
<h4>Directory structure</h4>
<p>The sub-directories are named according to a strict rule, but they are unknown to exist at design-time. Therefore the script needs to analyse the destination location and extract the key to be used for authorisation.<sup>1</sup></p>
<div>
<div class="wp-caption" style="text-align: left">Listing 3: Directory structure</div>
<pre class="brush: text">
/&lt;Day&gt;/&lt;Month&gt;/&lt;Year&gt;/&lt;MemberID&gt;
	&lt;Day&gt;:		00 - 31
	&lt;Month&gt;:		00 - 12
	&lt;Year&gt;:		00 - 99
	&lt;MemberID&gt;:	DDMMYY#####
</pre>
</div>
<div id="attachment_77" class="wp-caption alignnone" style="width: 118px"><a title="Directory structure" rel="lightbox-43" href="http://blog.itwarlocks.com/wp-content/uploads/2009/04/directory_structure.png"><img class="size-medium wp-image-77" title="Directory structure" src="http://blog.itwarlocks.com/wp-content/uploads/2009/04/directory_structure-108x300.png" alt="Directory structure" width="108" height="300" /></a><p class="wp-caption-text">Directory structure</p></div>
<p>This directory structure allows for a quite straight forward check to get the MemberID.<sup>2</sup></p>
<div>
<div class="wp-caption" style="text-align: left">Listing 3: .auth.php (version 0.0.2)</div>
<pre class="brush: php">
&lt;?php
/**
 * PHP based authentication for mod_dav
 * @author Jeffrey Ridout
 * @link http://blog.itwarlocks.com
 * @license http://creativecommons.org/licenses/by-sa/3.0
 * @date 2009-04-27
 * @version 0.0.2
 */

/**
 * $_SERVER[&#039;REQUEST_URI&#039;] contains the location accessed by the WebDAV client.
 * Using parse_url enables easy access to all URL parts.
 */
$requestURI = parse_url($_SERVER[&#039;REQUEST_URI&#039;]);

/**
 * Accessing some pages directly, like a page containing phpinfo(), will result in several
 * calls to .auth.php. These do not need to be logged.
 */
if ($requestURI[&#039;path&#039;] != $_SERVER[&#039;SCRIPT_NAME&#039;]) {
	$logFile = fopen(&#039;auth.log&#039;, &#039;a&#039;);
	fwrite($logFile, &quot;${_SERVER[&#039;PHP_AUTH_USER&#039;]}:${_SERVER[&#039;PHP_AUTH_PW&#039;]}@${requestURI[&#039;path&#039;]}\n&quot;);
	fclose($logFile);
}

/**
 * At stage 2 we can simulate a real authorisation lookup by using a simple array.
 * mod_auth_script catches custom headers to define the result to mod_auth.
 * auth-script:allow|deny|prompt Defines the authentication result.
 */
$blocked = array (
	&#039;01010154321&#039;,
	&#039;31037912345&#039;
);

/**
 * The directory name to search for might be in the path or destination filename.
 * .../blocked-dir
 * or
 * .../blocked-dir/
 * or
 * .../blocked-dir/...
 */
$path = dirname($requestURI[&#039;path&#039;]);
$dir = basename($path);
$match = basename($rURL[&#039;path&#039;]);
if (preg_match(&#039;#$\d{11}^#&#039;, $dir)) {
	$match = $dir;
}
if (!in_array($match, $blocked)) {
	header(&#039;auth-script:allow&#039;);
} else {
	/* Simulate authorisation by denying access.
	 * Normal authentication would return auth-script:prompt
	 */
	header(&#039;auth-script:deny&#039;);
}

/* EOF */
?&gt;
</pre>
</div>
<h4>Authorisation data</h4>
<p>The data that determines the authorisation can come from different sources; files, LDAP, RADIUS, database, &#8230;</p>
<p>In my case the authorisation result was retrieved from complex SQL using a stored procedure in a Sybase Database.</p>
<p>Whatever you use as your source of authentication/authorisation, remember that request can be asynchrounous and parallel. For a file base method that means never locking the file and opening it as &#8220;read-only&#8221;, for an external connection based method, it means using persistent connections.</p>
<h3>Conclusion</h3>
<p>Just because mod-dav and mod_auth don&#8217;t support your exact needs, doesn&#8217;t mean there is no solution. Using mod_auth_script to create your own tailored flexible solution works perfectly. As an added bonus this adds a new processing layer to PHP by allowing PHP to be executed at a much earlier stage. Using a PHP script to authorise also allows authorisation of non-existing destination URLs or destinations which access is based on complex business logic.</p>
<p><a href="/license/#cc-by-sa"><img class="size-full wp-image-95 alignleft" style="margin-right: 1.5em" title="Creative Commons: Attribution Share Alike" src="http://blog.itwarlocks.com/wp-content/uploads/2009/04/cc-by-sa_88x31.png" alt="Creative Commons: Attribution Share Alike" width="88" height="31" /></a>All code in this post is licensed under Creative Commons Attribution Share Alike.</p>
<ol class="footnotes"><li id="footnote_0_43" class="footnote">You may notice that year only has 2 digits. so no, it&#8217;s not Y2K safe&#8230;</li><li id="footnote_1_43" class="footnote">MemberID in this case is the Norwegian version of a social security number.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://blog.itwarlocks.com/2009/04/27/php-based-authentication-for-mod_dav/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Document Management System in Word using WebDAV</title>
		<link>http://blog.itwarlocks.com/2009/04/24/document-management-system-in-word-using-webdav/</link>
		<comments>http://blog.itwarlocks.com/2009/04/24/document-management-system-in-word-using-webdav/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 08:46:03 +0000</pubDate>
		<dc:creator><span property="dc:creator" resource="http://blog.itwarlocks.com/2009/04/24/document-management-system-in-word-using-webdav/">Jeffrey Ridout</span></dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[authorisation]]></category>
		<category><![CDATA[mod_auth]]></category>
		<category><![CDATA[mod_auth_script]]></category>
		<category><![CDATA[mod_dav]]></category>
		<category><![CDATA[office]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[visualbasic]]></category>
		<category><![CDATA[WebDAV]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[word]]></category>

		<guid isPermaLink="false">http://blog.itwarlocks.com/?p=64</guid>
		<description><![CDATA[Introduction
A customer I&#8217;m currently doing maintenance on their major application for, had an issue come up a couple of weeks ago where not all employees were to access all data any longer. The company deals with other companies and their employees, called members. The issue that came up caused a company wide policy to come [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>A customer I&#8217;m currently doing maintenance on their major application for, had an issue come up a couple of weeks ago where not all employees were to access all data any longer. The company deals with other companies and their employees, called members. The issue that came up caused a company wide policy to come in effect that meant that only specific users were to allow members or family of members to be accessed for a certain client company.</p>
<p>The application in question was easily modified since it already had support for authentication, so only authorisation for that specific company had to be added. (No we weren&#8217;t allowed to create a generic solution that would allow a reusable authorisation for multiple client companies. But discussing their policies is a whole different matter.)<span id="more-64"></span></p>
<h3>Case definition</h3>
<p>The users use the main application to create letters to be sent to client companies and members using Word. the application sends information about the specific company or member to Word using DDE and macros in the used templates fill in most of that information into the prewritten text. Another macro allows the user to save the document in a predefined location on a Windows Active Directory share. Yet another macro allows the user to get a list of all the documents stored for a specific company or member.</p>
<p>The problem was that everyone had full access to the shared location. So even though the information was protected through authentication and authorisation in the main application, the resulting letters containing vital information were still completely open.</p>
<h3>Solution</h3>
<p>There are actually several solutions, but I&#8217;m only going to blog about my favourite solution, since it involved quite some interesting techniques. This solution uses WebDAV instead of an Active Directory share.</p>
<h4>Requirements</h4>
<ol>
<li>Access to the documents needs to be authenticated</li>
<li>Access to the documents needs to be authorised</li>
<li>Authentication and authorisation data needs to be retrieved from a database (Sybase in this case)</li>
<li>The location needs to be accessible from Word</li>
<li>The location needs to be accessible from MainApp (pseudo name for the customer&#8217;s main application)</li>
</ol>
<h4>Implementation</h4>
<p>The MainApp already happened to be multi-tiered using an Apache webserver to provide services to the client. Since Exchange and SharePoint use the WebDAV protocol and mod_dav is available for Apache, I decided to try WebDAV. Since Office 2000, support for WebDAV (or &#8220;Web Folders&#8221;) has been present in Word, so there should be a way to access it through Word&#8217;s Visual Basic.</p>
<p>Implemenation articles:</p>
<ul>
<li><a href="http://blog.itwarlocks.com/2009/04/27/php-based-authentication-for-mod_dav/" target="_self">PHP based authentication for mod_dav</a></li>
<li><a href="http://blog.itwarlocks.com/2009/04/28/accessing-webdav-in-microsoft-word-visual-basic/" target="_self">Accessing WebDAV in Microsoft Word Visual Basic</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.itwarlocks.com/2009/04/24/document-management-system-in-word-using-webdav/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced) (user agent is rejected)

Served from: blog.itwarlocks.com @ 2010-09-05 05:19:09 -->