tips:htaccessauth
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
tips:htaccessauth [2009-03-11 16:14] – old revision restored 131.114.11.56 | tips:htaccessauth [2023-09-20 20:58] (current) – documentation of the old auth backends is removed Klap-in | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Setting up .htaccess user identification ====== | ||
- | ^ Yet another version of a htaccess backend can be found at [[htaccessauth2]]. (works with 2006-11-06 version)^ | ||
- | ^ A recent version of this backend is in the [[htaccessauth# | ||
- | |||
- | My DokuWiki is set up in a directory which is password protected by Apache, so this doesn' | ||
- | |||
- | < | ||
- | AuthType Basic | ||
- | AuthName " | ||
- | require valid-user | ||
- | </ | ||
- | |||
- | So everybody that accesses the wiki has already logged in, but not that DokuWiki is aware of. By adding an authentication method we can make acknowledge our users. To do this we create a new authentication method called htaccess, i.e. add a file to your_install_directory/ | ||
- | |||
- | <code php> | ||
- | <?php | ||
- | /** | ||
- | * .htaccess authentication backend | ||
- | * | ||
- | * Provide .htaccess style authentication | ||
- | * | ||
- | * @author | ||
- | * Additions: | ||
- | */ | ||
- | |||
- | /** | ||
- | * Check user+password [required auth function] | ||
- | * | ||
- | * Kinda trivial to check if the dir is protected by an .htaccess file. | ||
- | */ | ||
- | function auth_checkPass($user, | ||
- | if(isset($_SERVER[' | ||
- | return true; | ||
- | }else{ | ||
- | return false; | ||
- | } | ||
- | } | ||
- | |||
- | /** | ||
- | * Return user info [required auth function] | ||
- | * | ||
- | * Because I use auth_shadow I get my username from / | ||
- | * not all systems use this, or have gecos information, | ||
- | */ | ||
- | function auth_getUserData($user){ | ||
- | list($user, $pass, $uid, $gid, $extra) = posix_getpwnam($_SERVER[' | ||
- | list($username, | ||
- | |||
- | $data[' | ||
- | $data[' | ||
- | $data[' | ||
- | $data[' | ||
- | |||
- | return $data; | ||
- | } | ||
- | |||
- | /** | ||
- | * Create a new User [required auth function] | ||
- | * | ||
- | * This method does not allow for creating users. | ||
- | */ | ||
- | function auth_createUser($user, | ||
- | return null; | ||
- | } | ||
- | |||
- | ?> | ||
- | </ | ||
- | |||
- | To use this ' | ||
- | |||
- | < | ||
- | $conf[' | ||
- | </ | ||
- | |||
- | And now comes the small **hack**. Because users normally login by pressing the login button of the login form, DokuWiki only does authentication if the '' | ||
- | |||
- | <code php> | ||
- | if (isset($_SERVER[' | ||
- | </ | ||
- | |||
- | This first check in the if statement is trivial, but is there because of completeness and the second check is to prevent having to authenticate for every request. What you set '' | ||
- | |||
- | < | ||
- | $_SERVER[' | ||
- | $USERINFO = auth_getUserData($user); | ||
- | </ | ||
- | |||
- | instead of | ||
- | |||
- | < | ||
- | $USERINFO = auth_getUserData($user); | ||
- | $_SERVER[' | ||
- | </ | ||
- | |||
- | which I think is beter. Somebody explain please? Anyway in my case '' | ||
- | |||
- | All should be working now and ACL's should work to I guess (I don't use em). Oh, and you might want to change your template' | ||
- | |||
- | ====== The htaccess class ====== | ||
- | |||
- | ^ **UPDATED TO VERSION 1.2 --- 5 June, 2006**:\\ See [[htaccessauth# | ||
- | |||
- | In latest Dokuwiki, where [[:auth]] are php classes, the above method doesn' | ||
- | |||
- | My solution is based on both the first revision of this page and the [[auth: | ||
- | |||
- | The [[acl]] feature is supported and User and Group Management is the same as in [[auth: | ||
- | |||
- | ===== Installation ===== | ||
- | |||
- | Unpack the [[http:// | ||
- | |||
- | ===== htaccess.class.php ===== | ||
- | |||
- | Create a '' | ||
- | |||
- | <code php> | ||
- | <?php | ||
- | /** | ||
- | * Htaccess authentication backend | ||
- | * @license | ||
- | * @author | ||
- | * Version: 1.2 | ||
- | * last modified: 2006-06-05 11:46:00 | ||
- | * | ||
- | * Work based on the plaintext authentication backend: | ||
- | * @author | ||
- | * @author | ||
- | | ||
- | * and on the .htaccess authentication backed: | ||
- | * @author | ||
- | * Additions: | ||
- | * | ||
- | */ | ||
- | |||
- | define(' | ||
- | require_once(DOKU_AUTH.'/ | ||
- | |||
- | define(' | ||
- | |||
- | if(isset($_REQUEST[' | ||
- | | ||
- | | ||
- | | ||
- | |||
- | class auth_htaccess extends auth_basic { | ||
- | |||
- | var $users = null; | ||
- | var $_pattern = array(); | ||
- | |||
- | /** | ||
- | * Constructor | ||
- | * | ||
- | * Carry out sanity checks to ensure the object is | ||
- | * able to operate. Set capabilities. | ||
- | * | ||
- | * @author Samuele Tognini < | ||
- | */ | ||
- | | ||
- | global $conf; | ||
- | if (!@is_readable(AUTH_USERFILE)){ | ||
- | | ||
- | }else{ | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | } | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | } | ||
- | } | ||
- | |||
- | |||
- | /** | ||
- | * Check user+password [required auth function] | ||
- | * | ||
- | * Checks if the given user exists and the given | ||
- | * plaintext password is correct | ||
- | * | ||
- | * @author | ||
- | * Modified by Samuele Tognini < | ||
- | * @return | ||
- | */ | ||
- | | ||
- | global $conf; | ||
- | //To test. it should work on all enviroment, more than PHP_AUTH_USER. | ||
- | //change also the local.conf. | ||
- | //if (isset($_SERVER[' | ||
- | if(isset($_SERVER[' | ||
- | | ||
- | if ($userinfo === false) return false; | ||
- | | ||
- | }else{ | ||
- | | ||
- | } | ||
- | |||
- | } | ||
- | |||
- | /** | ||
- | * Logoff user | ||
- | * | ||
- | * @author | ||
- | * | ||
- | */ | ||
- | | ||
- | global $conf; | ||
- | //works only with basic http authentication | ||
- | if (isset($conf[' | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | exit; | ||
- | } else { | ||
- | // | ||
- | | ||
- | // | ||
- | if ($this-> | ||
- | | ||
- | } | ||
- | | ||
- | |||
- | /** | ||
- | * Return user info | ||
- | * | ||
- | * Returns info about the given user needs to contain | ||
- | * at least these fields: | ||
- | * | ||
- | * name string | ||
- | * mail string | ||
- | * grps array list of groups the user is in | ||
- | * | ||
- | * @author | ||
- | * Modified by Samuele Tognini < | ||
- | */ | ||
- | | ||
- | global $conf; | ||
- | if($this-> | ||
- | |||
- | //Every user gets the default group | ||
- | if (isset($conf[' | ||
- | | ||
- | // | ||
- | if (!isset($this-> | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | } | ||
- | // | ||
- | | ||
- | } | ||
- | return isset($this-> | ||
- | } | ||
- | |||
- | /** | ||
- | * Remove one or more users from the list of registered users | ||
- | * | ||
- | * @author | ||
- | * @param | ||
- | * @return | ||
- | */ | ||
- | | ||
- | |||
- | if (!is_array($users) || empty($users)) return 0; | ||
- | |||
- | if ($this-> | ||
- | |||
- | $deleted = array(); | ||
- | foreach ($users as $user) { | ||
- | if (isset($this-> | ||
- | } | ||
- | |||
- | if (empty($deleted)) return 0; | ||
- | |||
- | $pattern = '/ | ||
- | |||
- | if (io_deleteFromFile(AUTH_USERFILE, | ||
- | | ||
- | | ||
- | } | ||
- | |||
- | // problem deleting, reload the user list and count the difference | ||
- | $count = count($this-> | ||
- | $this-> | ||
- | $count -= $count($this-> | ||
- | return $count; | ||
- | } | ||
- | |||
- | /** | ||
- | * Create a new User | ||
- | * | ||
- | * Returns false if the user already exists, null when an error | ||
- | * occured and true if everything went well. | ||
- | * | ||
- | * The new user will be added to the default group by this | ||
- | * function if grps are not specified (default behaviour). | ||
- | * | ||
- | * @author | ||
- | * @author | ||
- | * Modified by Samuele Tognini < | ||
- | */ | ||
- | | ||
- | global $conf; | ||
- | |||
- | // user mustn' | ||
- | if ($this-> | ||
- | | ||
- | | ||
- | } | ||
- | |||
- | // set default group if no groups specified | ||
- | if (!is_array($grps)) $grps = array($conf[' | ||
- | |||
- | // prepare user line | ||
- | if ($mail == $user." | ||
- | $groups = join(',', | ||
- | | ||
- | $userline = join(':', | ||
- | if (io_saveFile(AUTH_USERFILE, | ||
- | // | ||
- | | ||
- | | ||
- | if (isset($conf[' | ||
- | | ||
- | | ||
- | } | ||
- | |||
- | msg(' | ||
- | return null; | ||
- | } | ||
- | |||
- | /** | ||
- | * Modify user data | ||
- | * | ||
- | * @author | ||
- | * Modified by Samuele Tognini < | ||
- | * @param | ||
- | * @param | ||
- | * @return | ||
- | */ | ||
- | | ||
- | global $conf; | ||
- | global $ACT; | ||
- | global $INFO; | ||
- | |||
- | // sanity checks, user must already exist in auth file and there must be something to change | ||
- | if (($userinfo = $this-> | ||
- | if (!is_array($changes) || !count($changes)) return true; | ||
- | // update userinfo with new data | ||
- | $newuser = $user; | ||
- | foreach ($changes as $field => $value) { | ||
- | if ($field == ' | ||
- | | ||
- | | ||
- | } | ||
- | | ||
- | } | ||
- | |||
- | // | ||
- | $a=array_search($conf[' | ||
- | if (is_numeric($a)) unset($userinfo[' | ||
- | |||
- | $groups = join(',', | ||
- | $newname= $userinfo[' | ||
- | $newmail=$userinfo[' | ||
- | //User description is the same of system user. Write a blank field. | ||
- | if ($newname==$this-> | ||
- | //Standard mail.Write a blank field. | ||
- | if (isset($conf[' | ||
- | | ||
- | $userline = join(':', | ||
- | | ||
- | if (!$this-> | ||
- | | ||
- | | ||
- | } | ||
- | |||
- | if (!io_saveFile(AUTH_USERFILE, | ||
- | | ||
- | // FIXME, user has been deleted but not recreated, should force a logout and redirect to login page | ||
- | $ACT == ' | ||
- | | ||
- | } | ||
- | |||
- | $this-> | ||
- | if (isset($conf[' | ||
- | | ||
- | return true; | ||
- | } | ||
- | |||
- | /** | ||
- | * Return a count of the number of user which meet $filter criteria | ||
- | * | ||
- | * @author | ||
- | */ | ||
- | | ||
- | |||
- | if($this-> | ||
- | |||
- | if (!count($filter)) return count($this-> | ||
- | |||
- | $count = 0; | ||
- | $this-> | ||
- | |||
- | foreach ($this-> | ||
- | | ||
- | } | ||
- | |||
- | return $count; | ||
- | } | ||
- | |||
- | /** | ||
- | * Bulk retrieval of user data | ||
- | * | ||
- | * @author | ||
- | * @param | ||
- | * @param | ||
- | * @param | ||
- | * @return | ||
- | */ | ||
- | | ||
- | global $conf; | ||
- | $grps=$conf[' | ||
- | if ($this-> | ||
- | | ||
- | |||
- | ksort($this-> | ||
- | |||
- | $i = 0; | ||
- | $count = 0; | ||
- | $out = array(); | ||
- | $this-> | ||
- | |||
- | foreach ($this-> | ||
- | // | ||
- | if (!empty($grps)) | ||
- | | ||
- | if ($this-> | ||
- | if ($i >= $start) { | ||
- | | ||
- | | ||
- | if (($limit > 0) && ($count >= $limit)) break; | ||
- | } | ||
- | $i++; | ||
- | } | ||
- | } | ||
- | return $out; | ||
- | } | ||
- | |||
- | /** | ||
- | * Return the user name information from system | ||
- | * | ||
- | * @author Samuele Tognini < | ||
- | */ | ||
- | | ||
- | $sys_name=''; | ||
- | $sys_user= posix_getpwnam($sys_user); | ||
- | if (@$sys_user) { | ||
- | | ||
- | | ||
- | | ||
- | } | ||
- | return $sys_name; | ||
- | } | ||
- | |||
- | /** | ||
- | * Load all user data | ||
- | * | ||
- | * loads the user file into a datastructure | ||
- | * | ||
- | * @author Samuele Tognini < | ||
- | */ | ||
- | | ||
- | global $conf; | ||
- | $this-> | ||
- | |||
- | if(!@file_exists(AUTH_USERFILE)) return; | ||
- | |||
- | $lines = file(AUTH_USERFILE); | ||
- | |||
- | foreach($lines as $line){ | ||
- | $line = preg_replace('/# | ||
- | $line = trim($line); | ||
- | | ||
- | $row = split(":", | ||
- | if (isset($row[3])) { | ||
- | | ||
- | | ||
- | //i try to get some user info from system | ||
- | if (empty($tmp_name)) { | ||
- | if ($sys_user= posix_getpwnam($row[0])) { | ||
- | list($id, $pass, $uid, $gid, $extra) = array_values($sys_user); | ||
- | list($username, | ||
- | $tmp_name = $username; | ||
- | } | ||
- | } | ||
- | if (empty($tmp_mail) && isset($conf[' | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | } else { | ||
- | | ||
- | | ||
- | } | ||
- | } | ||
- | } | ||
- | /** | ||
- | * return 1 if $user + $info match $filter criteria, 0 otherwise | ||
- | * | ||
- | * @author | ||
- | */ | ||
- | | ||
- | // FIXME | ||
- | |||
- | foreach ($this-> | ||
- | if ($item == ' | ||
- | if (!preg_match($pattern, | ||
- | } else if ($item == ' | ||
- | if (!count(preg_grep($pattern, | ||
- | } else { | ||
- | if (!preg_match($pattern, | ||
- | } | ||
- | } | ||
- | return 1; | ||
- | } | ||
- | |||
- | | ||
- | $this-> | ||
- | foreach ($filter as $item => $pattern) { | ||
- | // | ||
- | | ||
- | } | ||
- | } | ||
- | } | ||
- | |||
- | //Setup VIM: ex: et ts=2 enc=utf-8 : | ||
- | </ | ||
- | |||
- | |||
- | ===== htusers.auth.php ===== | ||
- | |||
- | Create a '' | ||
- | |||
- | If you want use the [[plugin: | ||
- | < | ||
- | #> chgrp www-data conf/ | ||
- | #> chmod 664 conf/ | ||
- | </ | ||
- | |||
- | The file format is '' | ||
- | * **name**: Login Name. It must be also in the .htaccess (Basic HTTP Authorization) file. | ||
- | * **full name**: User description. If empty, htaccessauth will try to get it from system (i.e. ''/ | ||
- | * **mail**: User mail. If empty and if it is configured the $conf[' | ||
- | * **groups**: User Groups. Comma separated user groups. | ||
- | |||
- | **Remember: | ||
- | |||
- | This is an example: | ||
- | |||
- | < | ||
- | # htusers.auth.php | ||
- | # <?php exit()?> | ||
- | # | ||
- | # Htaccess Userfile | ||
- | # | ||
- | # Format: | ||
- | # | ||
- | # user:full name: | ||
- | jack:The Admin:: | ||
- | allen::: | ||
- | neal:: | ||
- | </ | ||
- | |||
- | ===== acl.auth.php ===== | ||
- | |||
- | Copy the standard distribution file '' | ||
- | |||
- | For example: | ||
- | < | ||
- | #> chgrp www-data conf/ | ||
- | #> chmod 664 conf/ | ||
- | </ | ||
- | |||
- | ===== Configuration ===== | ||
- | |||
- | In order to use htaccessauth you must use these settings in your '' | ||
- | <code php> | ||
- | $conf[' | ||
- | if (isset($_SERVER[' | ||
- | </ | ||
- | |||
- | ==== Optional settings ==== | ||
- | |||
- | These settings in '' | ||
- | |||
- | === htaccess_defaultgrp === | ||
- | |||
- | Don't confuse it with [[config: | ||
- | Every user which gets Basic HTTP authorization, | ||
- | |||
- | In this way you don't need anymore to create users in [[htaccessauth# | ||
- | |||
- | Moreover, you can use acl to give custom permission to '' | ||
- | The [[plugin: | ||
- | |||
- | Note that '' | ||
- | |||
- | Thanks to [[dominique.launay@cru.fr|Dominique Launay]] for this great idea. | ||
- | |||
- | __Optional__ \\ | ||
- | __default__ : not used \\ | ||
- | __Example__ : $conf['" | ||
- | |||
- | === htaccess_domain === | ||
- | |||
- | You can either set a custom mail for every user in htusers.auth.php mail field, or leave it empty and set the htaccess_domain, | ||
- | |||
- | __Optional__ \\ | ||
- | __default__ : not used \\ | ||
- | __Example__ : $conf[' | ||
- | |||
- | === htaccess_realm === | ||
- | |||
- | The basic http authentication realm. | ||
- | |||
- | This is the AuthName directive in Apache web server configuration. You can find its value also in the login popup dialog. | ||
- | |||
- | If it's set then users will be able to logoff from Basic Http authentication using the logout button, if not then logout button will redirect users to the wiki main page. | ||
- | |||
- | A wrong value makes the logoff unsuccessful. | ||
- | |||
- | __Optional__ \\ | ||
- | __default__ : not used \\ | ||
- | __Example__ : $conf[" | ||
- | |||
- | **Note:** In order to logoff, click on dokuwiki ' | ||
- | |||
- | === htaccess_logout === | ||
- | |||
- | You can display a custom message to users that logout dokuwiki through the [[htaccessauth# | ||
- | |||
- | __Optional__ \\ | ||
- | __default__ : Successful logout. Retry login <a href=dokuwiki_dir> | ||
- | __Example__ : $conf[" | ||
- | |||
- | === htaccess_unauthurl === | ||
- | |||
- | This is a simple workaround to use when dokuwiki acl system denies access to users, that has authenticated themself successfully through the HTTP Basic authentication system. In this case, when htaccess_unauthurl value is also a denied page,a loop can be generated ,so pay attention to set it correctly. | ||
- | |||
- | Unuseful togheter with the [[htaccessauth# | ||
- | |||
- | __Optional__ \\ | ||
- | __default__ : .. (the directory upper dokuwiki, change it if it's a denied path) \\ | ||
- | __Example__ : $conf[" | ||
- | |||
- | ==== Others recommended options ==== | ||
- | |||
- | Others good options in '' | ||
- | |||
- | <code php> | ||
- | $conf[' | ||
- | $conf[' | ||
- | $conf[' | ||
- | </ | ||
- | |||
- | |||
- | ==== local.php configuration example ==== | ||
- | <code php> | ||
- | $conf[' | ||
- | $conf[' | ||
- | $conf[' | ||
- | $conf[' | ||
- | $conf[' | ||
- | $conf[' | ||
- | |||
- | if (isset($_SERVER[' | ||
- | </ | ||
- | |||
- | ===== Changelog ===== | ||
- | |||
- | * **2006-06-05 version 1.2**: | ||
- | * Added the [[htaccessauth# | ||
- | * Fixed some little bugs. | ||
- | |||
- | * **2006-03-27 version 1.1**: | ||
- | * [[plugin: | ||
- | * New logoff feature: allow an Http Basic Htaccess logout or make unuseful the logout button. | ||
- | * New custom mail option: set a custom mail or use the global domain variable. :!: Upgrade your [[htaccessauth# | ||
- | * New custom full name option: set a custom user full name or let htaccessauth retrive it from system. :!: Upgrade your [[htaccessauth# | ||
- | * Fixed the 'empty array' bug error. | ||
- | |||
- | * **2006-03-16 version 1.0**: | ||
- | * First release | ||
- | |||
- | |||
- | ===== Bugs ===== | ||
- | |||
- | * Every user in '' | ||
- | |||
- | < | ||
- | Warning: array_values(): | ||
- | Warning: Cannot modify header information - headers already sent by (output started at / | ||
- | Warning: Cannot modify header information - headers already sent by (output started at / | ||
- | </ | ||
- | |||
- | > Resolved in htaccessauth version 1.1. --- // | ||
- | |||
- | |||
- | * The example '' | ||
- | < | ||
- | # user: | ||
- | # user: | ||
- | </ | ||
- | instead of | ||
- | < | ||
- | # user:full name: | ||
- | </ | ||
- | as described on this wiki page. Cost me 20 minutes to figure out. | ||
- | |||
- | ====== Discussion ====== | ||
- | |||
- | Vi povas modifi la 331-a lino el ' | ||
- | |||
- | '' | ||
- | '' | ||
- | |||
- | > The new version of [[htaccessauth# | ||
- | |||
- | The module as provided only works if you are using mod_php. | ||
- | |||
- | <code php> | ||
- | if (isset($_SERVER[' | ||
- | </ | ||
- | |||
- | And in the module you need this extra block at line 77 ((At else statment of checkpass function)) | ||
- | <code php> | ||
- | elseif( isset($_SERVER[' | ||
- | | ||
- | if ($userinfo === false) return false; | ||
- | | ||
- | } | ||
- | </ | ||
- | >Reading documentation, | ||
- | |||
- | |||
- | Has anyone been able to get this to work on a Windows system using IIS? I modified htaccess.class.php starting on line 78 as follows: | ||
- | <code php> | ||
- | | ||
- | | ||
- | if ($userinfo === false) return false; | ||
- | | ||
- | | ||
- | $userinfo = $this-> | ||
- | if ($USERINFO == false) return false; | ||
- | return true; | ||
- | | ||
- | | ||
- | } | ||
- | </ | ||
- | --- // | ||
- | |||
- | >> | ||
- | |||
- | |||
- | **local.php code is mangled when using DW Configuration Manager** | ||
- | |||
- | This backend is great, but whenever I use DokuWiki' | ||
- | |||
- | if (isset($_SERVER[' | ||
- | |||
- | becomes | ||
- | |||
- | $conf[' | ||
- | |||
- | when changes are saved and causes DW to thrown an syntax error. | ||
- | |||
- | Hi, Have you tried to write it in conf/ | ||
- | |||
- | ===== Digest Authentication? | ||
- | |||
- | Hi, is it possible to get this working with Apache' | ||
- | > I have written an extension to this backend that supports digest authentication: |
tips/htaccessauth.1236784472.txt.gz · Last modified: 2011-03-18 11:37 (external edit)