Skip to content
Snippets Groups Projects
Commit 2570aa4d authored by Olav Morken's avatar Olav Morken
Browse files

Add LDAP & LDAPMulti authentication module.

This adds two authentication modules which are meant to replace auth/login.php
and auth/login-ldapmulti.php.


git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1372 44740490-163a-0410-bde0-09ae8108e29a
parent 49bd764a
No related branches found
No related tags found
No related merge requests found
...@@ -62,6 +62,94 @@ $config = array( ...@@ -62,6 +62,94 @@ $config = array(
'secret' => 'xxxxxxxxxxxxxxxx', 'secret' => 'xxxxxxxxxxxxxxxx',
), ),
/* Example of a LDAP authentication source. */
'example-ldap' => array(
'ldap:LDAP',
/* The hostname of the LDAP server. */
'hostname' => 'ldap.example.org',
/* Whether SSL/TLS should be used when contacting the LDAP server. */
'enable_tls' => FALSE,
/*
* Which attributes should be retrieved from the LDAP server.
* This can be an array of attribute names, or NULL, in which case
* all attributes are fetched.
*/
'attributes' => NULL,
/*
* The pattern which should be used to create the users DN given the username.
* %username% in this pattern will be replaced with the users username.
*
* This option is not used if the search.enable option is set to TRUE.
*/
'dnpattern' => 'uid=%username%,ou=people,dc=example,dc=org',
/*
* As an alternative to specifying a pattern for the users DN, it is possible to
* search for the username in a set of attributes. This is enabled by this option.
*/
'search.enable' => FALSE,
/*
* The DN which will be used as a base for the search.
* This can be a single string, in which case only that DN is searched, or an
* array of strings, in which case they will be searched in the order given.
*/
'search.base' => 'ou=people,dc=example,dc=org',
/*
* The attribute(s) the username should match against.
*
* This is an array with one or more attribute names. Any of the attributes in
* the array may match the value the username.
*/
'search.attributes' => array('uid', 'mail'),
/*
* The username & password the simpleSAMLphp should bind to before searching. If
* this is left as NULL, no bind will be performed before searching.
*/
'search.username' => NULL,
'search.password' => NULL,
),
/* Example of an LDAPMulti authentication source. */
'example-ldapmulti' => array(
'ldap:LDAPMulti',
/*
* A list of available LDAP servers / user groups. The value of each element is
* an array in the same format as an LDAP authentication source.
*/
'employees' => array(
/*
* A short name/description for this group. Will be shown in a dropdown list
* when the user logs on.
*
* This option can be a string or an array with language => text mappings.
*/
'description' => 'Employees',
/*
* The rest of the options are the same as those available for
* the LDAP authentication source.
*/
'hostname' => 'ldap.employees.example.org',
'dnpattern' => 'uid=%username%,ou=employees,dc=example,dc=org',
),
'students' => array(
'description' => 'Students',
'hostname' => 'ldap.students.example.org',
'dnpattern' => 'uid=%username%,ou=students,dc=example,dc=org',
),
),
); );
?> ?>
\ No newline at end of file
LDAP module
===========
The LDAP module provides a method for authenticating users against a
LDAP server. There are two seperate authentication modules:
`ldap:LDAP`
: Authenticate the user against a single LDAP server.
`ldap:LDAPMulti`
: Allow the user to chose one LDAP server to authenticate against.
`ldap:LDAP`
-----------
This module is used when you have an organization with a single LDAP
server with all the users. To create a LDAP authentication source, open
`config/authsources.php` in a text editor, and add an entry for the
authentication source:
'example-ldap' => array(
'ldap:LDAP',
/* The hostname of the LDAP server. */
'hostname' => 'ldap.example.org',
/* Whether SSL/TLS should be used when contacting the LDAP server. */
'enable_tls' => FALSE,
/*
* Which attributes should be retrieved from the LDAP server.
* This can be an array of attribute names, or NULL, in which case
* all attributes are fetched.
*/
'attributes' => NULL,
/*
* The pattern which should be used to create the users DN given the username.
* %username% in this pattern will be replaced with the users username.
*
* This option is not used if the search.enable option is set to TRUE.
*/
'dnpattern' => 'uid=%username%,ou=people,dc=example,dc=org',
/*
* As an alternative to specifying a pattern for the users DN, it is possible to
* search for the username in a set of attributes. This is enabled by this option.
*/
'search.enable' => FALSE,
/*
* The DN which will be used as a base for the search.
* This can be a single string, in which case only that DN is searched, or an
* array of strings, in which case they will be searched in the order given.
*/
'search.base' => 'ou=people,dc=example,dc=org',
/*
* The attribute(s) the username should match against.
*
* This is an array with one or more attribute names. Any of the attributes in
* the array may match the value the username.
*/
'search.attributes' => array('uid', 'mail'),
/*
* The username & password the simpleSAMLphp should bind to before searching. If
* this is left as NULL, no bind will be performed before searching.
*/
'search.username' => NULL,
'search.password' => NULL,
),
You should update the name of this authentication source
(`example-ldap`) to have a name which makes sense to your organization.
You also need to update the `hostname` and `dnpattern` options. The
`hostname` should be the hostname of your LDAP server, and the
`dnpattern` should be a pattern which can be used to generate the `dn`
of a user with a given username.
All other options have default values, and are not required.
### Searching for a user ###
Sometimes you cannot generate the users `dn` from the username, or you
may want to allow the user to authenticate with for example their email
address as the username. In this case, you can configure the LDAP
module to search for the users `dn` by searching for the username in
one or more attributes.
To enable searching, you must set the `search.enable` option to `TRUE`.
You must then configure the `search.base` and the `search.attributes`
options. The `search.base`-option must be the `dn` which should be used
as the base/root of the search. The `search.attributes`-option is an
array with attributes the username should be matched against.
The `dnpattern` option will not be used if searching is enabled.
Some LDAP servers may require authentication before a search can be
performed. In this case, you should configure the `search.username`
and `search.password` options. The `search.username` option is a `dn`
which can be used to perform a search, and the `search.password` option
is the password for that `dn`.
`ldap:LDAPMulti`
----------------
This module can be used if your organization has seperate groups with
seperate LDAP servers or seperate LDAP configurations. To use this
authentication module, open `config/authsources.php` in a text editor,
and add an entry which uses this module:
'example-ldapmulti' => array(
'ldap:LDAPMulti',
/*
* A list of available LDAP servers. The index is only an identifier,
* and can be any string. The value of each element is an array in the
* same format as an LDAP authentication source.
*/
'employees' => array(
/*
* A short name/description for this group. Will be shown in a dropdown list
* when the user logs on.
*
* This option can be a string or an array with language => text mappings.
*/
'description' => 'Employees',
/*
* The rest of the options are the same as those available for
* the LDAP authentication source.
*/
'hostname' => 'ldap.employees.example.org',
'dnpattern' => 'uid=%username%,ou=employees,dc=example,dc=org',
),
'students' => array(
'description' => 'Students',
'hostname' => 'ldap.students.example.org',
'dnpattern' => 'uid=%username%,ou=students,dc=example,dc=org',
),
),
The name of the authentication source (`example-ldapmulti`) should be
changed to something that makes sense for your organization. Each entry
in the configuration represents the configuration for one group of
users. The `description`-option in each group is the name of the group,
and will be shown to the user in a dropdown list on the login page.
The `description`-option can also be an array with descriptions in
different languages:
'description' => array(
'en' => 'Employees',
'no' => 'Ansatte',
),
All options from the `ldap:LDAP` configuration can be used in each
group, and you should refer to the documentation for that module for
more information about available options.
<?php
/**
* LDAP authentication source.
*
* See the ldap-entry in config-templates/authsources.php for information about
* configuration of this authentication source.
*
* This class is based on www/auth/login.php.
*
* @package simpleSAMLphp
* @version $Id$
*/
class sspmod_ldap_Auth_Source_LDAP extends sspmod_core_Auth_UserPassBase {
/**
* A LDAP configuration object.
*/
private $ldapConfig;
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public function __construct($info, $config) {
assert('is_array($info)');
assert('is_array($config)');
/* Call the parent constructor first, as required by the interface. */
parent::__construct($info, $config);
$this->ldapConfig = new sspmod_ldap_ConfigHelper($config,
'Authentication source ' . var_export($this->authId, TRUE));
}
/**
* Attempt to log in using the given username and password.
*
* @param string $username The username the user wrote.
* @param string $password The password the user wrote.
* @return array Associative array with the users attributes.
*/
protected function login($username, $password) {
assert('is_string($username)');
assert('is_string($password)');
return $this->ldapConfig->login($username, $password);
}
}
?>
\ No newline at end of file
<?php
/**
* LDAP authentication source.
*
* See the ldap-entry in config-templates/authsources.php for information about
* configuration of this authentication source.
*
* This class is based on www/auth/login.php.
*
* @package simpleSAMLphp
* @version $Id$
*/
class sspmod_ldap_Auth_Source_LDAPMulti extends sspmod_core_Auth_UserPassOrgBase {
/**
* An array with descriptions for organizations.
*/
private $orgs;
/**
* An array of organization IDs to LDAP configuration objects.
*/
private $ldapOrgs;
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public function __construct($info, $config) {
assert('is_array($info)');
assert('is_array($config)');
/* Call the parent constructor first, as required by the interface. */
parent::__construct($info, $config);
$this->orgs = array();
$this->ldapOrgs = array();
foreach ($config as $orgId => $orgCfg) {
if (array_key_exists('description', $orgCfg)) {
$this->orgs[$orgId] = $orgCfg['description'];
} else {
$this->orgs[$orgId] = $orgId;
}
$orgCfg = new sspmod_ldap_ConfigHelper($orgCfg,
'Authentication source ' . var_export($this->authId, TRUE) .
', organization ' . var_export($orgId, TRUE));
$this->ldapOrgs[$orgId] = $orgCfg;
}
}
/**
* Attempt to log in using the given username and password.
*
* @param string $username The username the user wrote.
* @param string $password The password the user wrote.
* @param string $org The organization the user chose.
* @return array Associative array with the users attributes.
*/
protected function login($username, $password, $org) {
assert('is_string($username)');
assert('is_string($password)');
if (!array_key_exists($org, $this->ldapOrgs)) {
/* The user has selected an organization which doesn't exist anymore. */
SimpleSAML_Logger::warning('Authentication source ' . var_export($this->authId, TRUE) .
': Organization seems to have disappeared while the user logged in.' .
' Organization was ' . var_export($org, TRUE));
throw new SimpleSAML_Error_Error('WRONGUSERPASS');
}
return $this->ldapOrgs[$org]->login($username, $password);
}
/**
* Retrieve list of organizations.
*
* @return array Associative array with the organizations.
*/
protected function getOrganizations() {
return $this->orgs;
}
}
?>
\ No newline at end of file
<?php
/**
* LDAP authentication source configuration parser.
*
* See the ldap-entry in config-templates/authsources.php for information about
* configuration of these options.
*
* @package simpleSAMLphp
* @version $Id$
*/
class sspmod_ldap_ConfigHelper {
/**
* String with the location of this configuration.
* Used for error reporting.
*/
private $location;
/**
* The hostname of the LDAP server.
*/
private $hostname;
/**
* Whether we should use TLS/SSL when contacting the LDAP server.
*/
private $enableTLS;
/**
* Whether we need to search for the users DN.
*/
private $searchEnable;
/**
* The username we should bind with before we can search for the user.
*/
private $searchUsername;
/**
* The password we should bind with before we can search for the user.
*/
private $searchPassword;
/**
* Array with the base DN(s) for the search.
*/
private $searchBase;
/**
* The attributes which should match the username.
*/
private $searchAttributes;
/**
* The DN pattern we should use to create the DN from the username.
*/
private $dnPattern;
/**
* The attributes we should fetch. Can be NULL in which case we will fetch all attributes.
*/
private $attributes;
/**
* Constructor for this configuration parser.
*
* @param array $config Configuration.
* @param string $location The location of this configuration. Used for error reporting.
*/
public function __construct($config, $location) {
assert('is_array($config)');
assert('is_string($location)');
$this->location = $location;
/* Parse configuration. */
$config = SimpleSAML_Configuration::loadFromArray($config, $location);
$this->hostname = $config->getString('hostname');
$this->enableTLS = $config->getBoolean('enable_tls', FALSE);
$this->searchEnable = $config->getBoolean('search.enable', FALSE);
if ($this->searchEnable) {
$this->searchUsername = $config->getString('search.username', NULL);
if ($this->searchUsername !== NULL) {
$this->searchPassword = $config->getString('search.password');
}
$this->searchBase = $config->getString('search.base');
$this->searchAttributes = $config->getArray('search.attributes');
} else {
$this->dnPattern = $config->getString('dnpattern');
}
$this->attributes = $config->getArray('attributes', NULL);
}
/**
* Attempt to log in using the given username and password.
*
* Will throw a SimpleSAML_Error_Error('WRONGUSERPASS') if the username or password is wrong.
* If there is a configuration problem, an Exception will be thrown.
*
* @param string $username The username the user wrote.
* @param string $password The password the user wrote.
* @return array Associative array with the users attributes.
*/
public function login($username, $password) {
assert('is_string($username)');
assert('is_string($password)');
$ldap = new SimpleSAML_Auth_LDAP($this->hostname, $this->enableTLS);
if (!$this->searchEnable) {
$ldapusername = addcslashes($username, ',+"\\<>;*');
$dn = str_replace('%username%', $ldapusername, $this->dnPattern);
} else {
if ($this->searchUsername !== NULL) {
if(!$ldap->bind($this->searchUsername, $this->searchPassword)) {
throw new Exception('Error authenticating using search username & password.');
}
}
$dn = $ldap->searchfordn($this->searchBase, $this->searchAttributes, $username, TRUE);
if ($dn === NULL) {
/* User not found with search. */
SimpleSAML_Logger::info($this->location . ': Unable to find users DN. username=\'' . $username . '\'');
throw new SimpleSAML_Error_Error('WRONGUSERPASS');
}
}
if (!$ldap->bind($dn, $password)) {
SimpleSAML_Logger::info($this->location . ': '. $username . ' failed to authenticate. DN=' . $dn);
throw new SimpleSAML_Error_Error('WRONGUSERPASS');
}
return $ldap->getAttributes($dn, $this->attributes);
}
}
?>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment