1 package Catalyst::Authentication::Store::LDAP;
6 our $VERSION = '1.015';
8 use Catalyst::Authentication::Store::LDAP::Backend;
11 my ( $class, $config, $app ) = @_;
12 return Catalyst::Authentication::Store::LDAP::Backend->new(
24 Catalyst::Authentication::Store::LDAP
25 - Authentication from an LDAP Directory.
35 default_realm => "ldap",
40 password_field => "password",
41 password_type => "self_check",
44 binddn => "anonymous",
45 bindpw => "dontcarehow",
47 ldap_server => "ldap.yourcompany.com",
48 ldap_server_options => { timeout => 30 },
49 role_basedn => "ou=groups,ou=OxObjects,dc=yourcompany,dc=com",
51 role_filter => "(&(objectClass=posixGroup)(memberUid=%s))",
53 role_search_options => { deref => "always" },
55 role_search_as_user => 0,
57 start_tls_options => { verify => "none" },
58 entry_class => "MyApp::LDAP::Entry",
60 user_basedn => "ou=people,dc=yourcompany,dc=com",
62 user_filter => "(&(objectClass=posixAccount)(uid=%s))",
63 user_scope => "one", # or "sub" for Active Directory
64 user_search_options => {
66 attrs => [qw( distinguishedname name mail )],
68 user_results_filter => sub { return shift->pop_entry },
76 my ( $self, $c ) = @_;
79 id => $c->req->param("login"),
80 password => $c->req->param("password")
82 $c->res->body("Welcome " . $c->user->username . "!");
87 This plugin implements the L<Catalyst::Authentication> v.10 API. Read that documentation first if
88 you are upgrading from a previous version of this plugin.
90 This plugin uses C<Net::LDAP> to let your application authenticate against
91 an LDAP directory. It has a pretty high degree of flexibility, given the
92 wide variation of LDAP directories and schemas from one system to another.
94 It authenticates users in two steps:
96 1) A search of the directory is performed, looking for a user object that
97 matches the username you pass. This is done with the bind credentials
98 supplied in the "binddn" and "bindpw" configuration options.
100 2) If that object is found, we then re-bind to the directory as that object.
101 Assuming this is successful, the user is Authenticated.
103 =head1 CONFIGURATION OPTIONS
105 =head2 Configuring with YAML
107 Set Configuration to be loaded via Config.yml in YourApp.pm
109 use YAML qw(LoadFile);
110 use Path::Class 'file';
114 file(__PACKAGE__->config->{home}, 'Config.yml')
118 Settings in Config.yml (adapt these to whatever configuration format you use):
120 # Config for Store::LDAP
127 password_field: password
128 password_type: self_check
131 ldap_server: ldap.yourcompany.com
139 user_basedn: ou=people,dc=yourcompany,dc=com
140 user_filter: (&(objectClass=posixAccount)(uid=%s))
146 role_basedn: ou=groups,ou=OxObjects,dc=yourcompany,dc=com
147 role_filter: (&(objectClass=posixGroup)(memberUid=%s))
155 B<NOTE:> The settings above reflect the default values for OpenLDAP. If you
156 are using Active Directory instead, Matija Grabnar suggests that the following
157 tweeks to the example configuration will work:
159 user_basedn: ou=Domain Users,ou=Accounts,dc=mycompany,dc=com
160 user_field: samaccountname
161 user_filter: (sAMAccountName=%s)
164 He also notes: "I found the case in the value of user_field to be significant:
165 it didn't seem to work when I had the mixed case value there."
169 This should be the hostname of your LDAP server.
171 =head2 ldap_server_options
173 This should be a hashref containing options to pass to L<Net::LDAP>->new().
174 See L<Net::LDAP> for the full list.
178 This should be the DN of the object you wish to bind to the directory as
179 during the first phase of authentication. (The user lookup phase)
181 If you supply the value "anonymous" to this option, we will bind anonymously
182 to the directory. This is the default.
186 This is the password for the initial bind.
190 If this is set to 1, we will convert the LDAP connection to use SSL.
192 =head2 start_tls_options
194 This is a hashref, which contains the arguments to the L<Net::LDAP> start_tls
195 method. See L<Net::LDAP> for the complete list of options.
199 This is the basedn for the initial user lookup. Usually points to the
200 top of your "users" branch; ie "ou=people,dc=yourcompany,dc=com".
204 This is the LDAP Search filter used during user lookup. The special string
205 '%s' will be replaced with the username you pass to $c->login. By default
206 it is set to '(uid=%s)'. Other possibly useful filters:
208 (&(objectClass=posixAccount)(uid=%s))
209 (&(objectClass=User)(cn=%s))
213 This specifies the scope of the search for the initial user lookup. Valid
214 values are "base", "one", and "sub". Defaults to "sub".
218 This is the attribute of the returned LDAP object we will use for their
219 "username". This defaults to "uid". If you had user_filter set to:
221 (&(objectClass=User)(cn=%s))
223 You would probably set this to "cn". You can also set it to an array,
224 to allow more than one login field. The first field will be returned
225 as identifier for the user.
227 =head2 user_search_options
229 This takes a hashref. It will append it's values to the call to
230 L<Net::LDAP>'s "search" method during the initial user lookup. See
231 L<Net::LDAP> for valid options.
233 Be careful not to specify:
239 As they are already taken care of by other configuration options.
241 =head2 user_results_filter
243 This is a Perl CODE ref that can be used to filter out multiple results
244 from your LDAP query. In theory, your LDAP query should only return one result
245 and find_user() will throw an exception if it encounters more than one result.
246 However, if you have, for whatever reason, a legitimate reason for returning
247 multiple search results from your LDAP query, use C<user_results_filter> to filter
248 out the LDAP entries you do not want considered. Your CODE ref should expect
249 a single argument, a Net::LDAP::Search object, and it should return exactly one
250 value, a Net::LDAP::Entry object.
254 user_results_filter => sub {
255 my $search_obj = shift;
256 foreach my $entry ($search_obj->entries) {
257 return $entry if my_match_logic( $entry );
259 return undef; # i.e., no match
264 Whether or not to enable role lookups. It defaults to true; set it to 0 if
265 you want to always avoid role lookups.
269 This should be the basedn where the LDAP Objects representing your roles are.
273 This should be the LDAP Search filter to use during the role lookup. It
274 defaults to '(memberUid=%s)'. The %s in this filter is replaced with the value
275 of the "role_value" configuration option.
277 So, if you had a role_value of "cn", then this would be populated with the cn
278 of the User's LDAP object. The special case is a role_value of "dn", which
279 will be replaced with the User's DN.
283 This specifies the scope of the search for the user's role lookup. Valid
284 values are "base", "one", and "sub". Defaults to "sub".
288 Should be set to the Attribute of the Role Object's returned during Role lookup you want to use as the "name" of the role. Defaults to "CN".
292 This is the attribute of the User object we want to use in our role_filter.
293 If this is set to "dn", we will use the User Objects DN.
295 =head2 role_search_options
297 This takes a hashref. It will append it's values to the call to
298 L<Net::LDAP>'s "search" method during the user's role lookup. See
299 L<Net::LDAP> for valid options.
301 Be careful not to specify:
307 As they are already taken care of by other configuration options.
309 =head2 role_search_as_user
311 By default this setting is false, and the role search will be performed
312 by binding to the directory with the details in the I<binddn> and I<bindpw>
313 fields. If this is set to false, then the role search will instead be
314 performed when bound as the user you authenticated as.
318 The name of the class of LDAP entries returned. This class should
319 exist and is expected to be a subclass of Net::LDAP::Entry
323 The name of the class of user object returned. By default, this is
324 L<Catalyst::Authentication::Store::LDAP::User>.
330 This method will populate
331 L<Catalyst::Plugin::Authentication/default_auth_store> with this object.
335 Adam Jacob <holoway@cpan.org>
337 Some parts stolen shamelessly and entirely from
338 L<Catalyst::Plugin::Authentication::Store::Htpasswd>.
340 Currently maintained by Peter Karman <karman@cpan.org>.
344 To nothingmuch, ghenry, castaway and the rest of #catalyst for the help. :)
348 L<Catalyst::Authentication::Store::LDAP>,
349 L<Catalyst::Authentication::Store::LDAP::User>,
350 L<Catalyst::Authentication::Store::LDAP::Backend>,
351 L<Catalyst::Plugin::Authentication>,
354 =head1 COPYRIGHT & LICENSE
356 Copyright (c) 2005 the aforementioned authors. All rights
357 reserved. This program is free software; you can redistribute
358 it and/or modify it under the same terms as Perl itself.