<?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>baseciq.org &#187; fastcgi</title>
	<atom:link href="http://www.baseciq.org/tagi/fastcgi/feed" rel="self" type="application/rss+xml" />
	<link>http://www.baseciq.org</link>
	<description></description>
	<lastBuildDate>Wed, 26 Oct 2011 09:01:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Autoryzacja w Apache 2.2 w zewnętrznym programie (i/lub bazie danych MySQL) za pomocą FastCGI</title>
		<link>http://www.baseciq.org/2008/01/02/autoryzacja-w-apache-22-w-zewnetrznym-programie-ilub-bazie-danych-mysql-za-pomoca-fastcgi</link>
		<comments>http://www.baseciq.org/2008/01/02/autoryzacja-w-apache-22-w-zewnetrznym-programie-ilub-bazie-danych-mysql-za-pomoca-fastcgi#comments</comments>
		<pubDate>Wed, 02 Jan 2008 10:00:44 +0000</pubDate>
		<dc:creator>Baseciq</dc:creator>
				<category><![CDATA[howtos]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.baseciq.org/?p=121</guid>
		<description><![CDATA[Apache ma sporo sposobów na autoryzację. Jednakże, jakoś nikt za bardzo nie pomyślał o autoryzacji w bazie danych MySQL. Oczywiście, są moduły auth_mysql przeróżne, ale mi się niestety nie udało ich skompilować. Jest także moduł mod_authnz_external, jednakże ma jedną wadę &#8211; uruchamia proces autoryzacyjny przy praktycznie każdym requeście, a to nie jest zbyt porządane. Jedną [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Apache ma sporo sposobów na autoryzację. Jednakże, jakoś nikt za bardzo nie pomyślał o autoryzacji w bazie danych MySQL. Oczywiście, są moduły auth_mysql przeróżne, ale mi się niestety nie udało ich skompilować. Jest także moduł mod_authnz_external, jednakże ma jedną wadę &#8211; uruchamia proces autoryzacyjny przy praktycznie każdym requeście, a to nie jest zbyt porządane.</p>
<p style="text-align: justify;">Jedną z metod, na szybkie wykonywanie CGI, jest mechanizm FastCGI. Poza swoimi podstawowymi funkcjami, jest on w stanie także uruchomić jakiś proces i korzystać z niego jako z backendu do autoryzacji.</p>
<p><span id="more-121"></span><br clear="both"/><div class="adsense-single" id="adsense-single"><!-- jeżeli nie lubisz reklam, to sobie wytniesz po id obiektu... --> 
	<script type="text/javascript"> google_ad_client = "pub-3850786112207919"; google_ad_slot = "3874219152"; google_ad_width = 468; google_ad_height = 60; </script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
 </div></p>
<p>Co będziesz potrzebować?</p>
<ul>
<li>działającego Apache</li>
<li>skompilowany i zainstalowany moduł FastCGI</li>
<li>trochę wiedzy z konfiguracji Apache</li>
<li>no i oczywiście pomysłu na backend autoryzacyjny</li>
</ul>
<p style="text-align: justify;">Z pierwszymi dwoma rzeczami powinieneś sobie poradzić bez większych problemów instalując PLD :) Pozycja nr. 3 rozumie się chyba sama przez siebie jeżeli tutaj zawitałeś. Z czwartym składnikiem rozwiązania, niestety musisz poradzić sobie sam. Ale i na to postaram się coś poradzić.</p>
<p><strong>Let&#8217;s go</strong></p>
<p style="text-align: justify;">Kilka słów wstępu. Od czasów Apache 2.2, moduł auth (czy może powinienem go nazwać AuthBasic?) powoduje to, iż Apache wymaga podania &#8222;dostawcy&#8221; podstawowej autoryzacji za pomocą dyrektywy <strong>AuthBasicProvider</strong>. Niestety, z tego co mi wiadomo (pamiętaj: mogę się mylić), FastCGI nie rejestruje się w Apache jako dostawca tejże autoryzacji. Problem został zauważony, opisany i załatany w Debianie (więcej informacji <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=414185" target="_blank">tutaj</a>) a także w PLD. Jeżeli posiadasz inną dystrybucję, na stronie z raportem błędu debiana jest link do łatki debianowej która łata także i ten problem. Niestety, ja nie posiadam nic innego niż PLD i Debian, więc nie poprowadzę Cię na piechotę.</p>
<p style="text-align: justify;">Przejdźmy do rzeczy. Oto przykładowa konfiguracja Apache aby się autoryzował za pomocą zewnętrznego skryptu:</p>
<pre>&lt;Directory /home/cokolwiek&gt;
                AuthType Basic
                AuthName "ProtectedRealm"
                AuthBasicProvider fastcgi
                FastCgiAuthenticator /usr/local/sbin/http-auth-lms.pl
                FastCgiAuthenticatorAuthoritative On
                require valid-user
&lt;/Directory&gt;</pre>
<p style="text-align: justify;">Jak widać, konfiguracja w sumie zbyt dużo nie odbiega od normalnej autoryzacji, poza podaniem ścieżki do skryptu w perlu. W moim wypadku jest to skrypt który autoryzuje się w bazie LMS&#8217;a. Po co i dlaczego, piszę w tekście który też gdzieś tutaj jest :)</p>
<p style="text-align: justify;">Skrypt znalazłem na jednej ze stron i go odpowiednio dostosowałem (czytaj: wykorzystałem tylko szkielet obsługi CGI), ale niestety nie pamiętam gdzie i u kogo. w perlu wygląda tak:</p>
<pre><span class="c8080ff">#!/usr/bin/perl -Tw</span>

<span class="cffff00">use </span>FCGI;
<span class="cffff00">use </span>CGI (<span class="cff40ff">'</span><span class="cff40ff">:standard</span><span class="cff40ff">'</span>);
<span class="cffff00">use </span>DBI;

<span class="c00ffff"># konfiguracja dostępu do bazy danych:</span>

<span class="cffff00">my</span> <span class="c00ffff">$dbhost</span>=<span class="cff40ff">"</span><span class="cff40ff">localhost</span><span class="cff40ff">"</span>;
<span class="cffff00">my</span> <span class="c00ffff">$dbuser</span>=<span class="cff40ff">"</span><span class="cff40ff">mysql</span><span class="cff40ff">"</span>;
<span class="cffff00">my</span> <span class="c00ffff">$dbpw</span>=<span class="cff40ff">"</span><span class="cff40ff">p4ssw0rd</span><span class="cff40ff">"</span>;
<span class="cffff00">my</span> <span class="c00ffff">$dbname</span>=<span class="cff40ff">"</span><span class="cff40ff">lms</span><span class="cff40ff">"</span>;

<span class="cffff00">my</span> <span class="c00ffff">$dbport</span>=<span class="cff40ff">"</span><span class="cff40ff">3306</span><span class="cff40ff">"</span>;

<span class="c00ffff"># połączenie do bazy jako takiej:</span>

<span class="cffff00">my</span> <span class="c00ffff">$dbh</span> = DBI-&gt;<span class="cffff00">connect</span>(
		<span class="cff40ff">"</span><span class="cff40ff">DBI:mysql:database=</span><span class="c00ffff">$dbname</span><span class="cff40ff">:host=</span><span class="c00ffff">$dbhost</span><span class="cff40ff">:port=</span><span class="c00ffff">$dbport</span><span class="cff40ff">"</span>,
		<span class="c00ffff">$dbuser</span>,
		<span class="c00ffff">$dbpw</span>,
		{<span class="cff40ff">PrintError</span>=&gt;<span class="cff40ff">0</span>}
);

<span class="c00ffff"># zapytanie o hasło:</span>

<span class="cffff00">my</span> <span class="c00ffff">$verify_passwd</span> = <span class="c00ffff">$dbh</span>-&gt;prepare(
		<span class="cff40ff">'</span><span class="cff40ff">select passwd from users where login=?</span><span class="cff40ff">'</span>
);

<span class="cffff00">my</span> <span class="c00ffff">$s200</span> = <span class="cff40ff">'</span><span class="cff40ff">200 OK</span><span class="cff40ff">'</span>;

<span class="cffff00">my</span> <span class="c00ffff">$s401</span> = <span class="cff40ff">'</span><span class="cff40ff">401 Authorization Required</span><span class="cff40ff">'</span>;

<span class="cffff00">my</span> <span class="c00ffff">$q</span> = FCGI::Request();

<span class="cffff00">while</span> (<span class="c00ffff">$q</span>-&gt;Accept &gt;= <span class="cff40ff">0</span>) {
		<span class="cffff00">my</span> <span class="c00ffff">$u</span> = <span class="cff40ff">''</span>;
		<span class="cffff00">my</span> <span class="c00ffff">$p</span> = <span class="cff40ff">''</span>;

		<span class="cffff00">if</span> (<span class="cffff00">exists</span> <span class="c00ffff">$ENV</span>{REMOTE_USER})   { <span class="c00ffff">$u</span> = <span class="c00ffff">$ENV</span>{REMOTE_USER}; }
		<span class="cffff00">if</span> (<span class="cffff00">exists</span> <span class="c00ffff">$ENV</span>{REMOTE_PASSWD}) { <span class="c00ffff">$p</span> = <span class="c00ffff">$ENV</span>{REMOTE_PASSWD}; }

		<span class="cffff00">if</span> (<span class="cffff00">not</span> (<span class="c00ffff">$u</span> <span class="cffff00">and</span> <span class="c00ffff">$p</span>)) {
				spit(<span class="c00ffff">$s401</span>);
		} <span class="cffff00">else</span> {

				<span class="c00ffff"># na wszelki wypadek - jeżeli baza danych się rozłączyła,</span>

				<span class="c00ffff"># połączmy się ponownie i przygotujmy zapytanie:</span>

				<span class="cffff00">unless</span>(<span class="cffff00">defined</span> <span class="c00ffff">$dbh</span> <span class="cffff00">and</span> <span class="cffff00">defined</span> <span class="c00ffff">$verify_passwd</span>) {
						<span class="c00ffff">$dbh</span> = DBI-&gt;<span class="cffff00">connect</span>(<span class="cff40ff">"</span><span class="cff40ff">DBI:mysql:database=</span><span class="c00ffff">$dbname</span><span class="cff40ff">:host=</span><span class="c00ffff">$dbhost</span><span class="cff40ff">:port=</span><span class="c00ffff">$dbport</span><span class="cff40ff">"</span>,<span class="c00ffff">$dbuser</span>,<span class="c00ffff">$dbpw</span>,{<span class="cff40ff">PrintError</span>=&gt;<span class="cff40ff">0</span>});
						<span class="c00ffff">$verify_passwd</span> = <span class="c00ffff">$dbh</span>-&gt;prepare(<span class="cff40ff">'</span><span class="cff40ff">select passwd from users where login=?</span><span class="cff40ff">'</span>);
				}

				<span class="c00ffff">$verify_passwd</span>-&gt;execute(<span class="c00ffff">$u</span>) <span class="cffff00">if</span>(<span class="cffff00">defined</span> <span class="c00ffff">$verify_passwd</span>);

				<span class="cffff00">my</span> (<span class="c00ffff">$dp</span>) = <span class="c00ffff">$verify_passwd</span>-&gt;fetchrow_array;

				<span class="cffff00">if</span> (<span class="cffff00">not</span> (<span class="c00ffff">$dp</span>)) {
						spit(<span class="c00ffff">$s401</span>);
				} <span class="cffff00">elsif</span> (<span class="c00ffff">$dp</span> <span class="cffff00">eq</span> <span class="cffff00">crypt</span>(<span class="c00ffff">$p</span>, <span class="c00ffff">$dp</span>)) {
						spit(<span class="c00ffff">$s200</span>);
				} <span class="cffff00">else</span> {
						spit(<span class="c00ffff">$s401</span>);
				}
		}
}

<span class="cffff00">undef</span> <span class="c00ffff">$verify_passwd</span>;
<span class="c00ffff">$dbh</span>-&gt;disconnect <span class="cffff00">if</span>(<span class="cffff00">defined</span> <span class="c00ffff">$dbh</span>);
<span class="cffff00">undef</span> <span class="c00ffff">$dbh</span>;
<span class="cffff00">exit</span> <span class="cff40ff">0</span>;

<span class="cffff00">sub</span><span class="c00ffff"> </span><span class="c00ffff">spit</span><span class="c00ffff"> </span>{
		<span class="cffff00">my</span> <span class="c00ffff">$s</span> = <span class="cffff00">shift</span>;
		<span class="cffff00">print</span> header(<span class="cff40ff">'</span><span class="cff40ff">text/plain</span><span class="cff40ff">'</span>, <span class="c00ffff">$s</span>), <span class="c00ffff">$s</span>;
}</pre>
<p>Jak widać, skrypt ten autoryzuje się w bazie LMSa. Dzięki niemu, masz jakiś przykład jak to dalej pociągnąć i jak sobie z tym poradzić :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.baseciq.org/2008/01/02/autoryzacja-w-apache-22-w-zewnetrznym-programie-ilub-bazie-danych-mysql-za-pomoca-fastcgi/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

