Version 1.014
[catagits/Catalyst-Authentication-Store-LDAP.git] / lib / Catalyst / Authentication / Store / LDAP.pm
CommitLineData
f66d606b 1package Catalyst::Authentication::Store::LDAP;
2
3use strict;
4use warnings;
5
62534b1b 6our $VERSION = '1.014';
f66d606b 7
8use Catalyst::Authentication::Store::LDAP::Backend;
9
10sub new {
11 my ( $class, $config, $app ) = @_;
12 return Catalyst::Authentication::Store::LDAP::Backend->new(
13 $config);
14}
15
161;
17
18__END__
19
20=pod
21
22=head1 NAME
23
24Catalyst::Authentication::Store::LDAP
25 - Authentication from an LDAP Directory.
26
27=head1 SYNOPSIS
28
24ff036b 29 use Catalyst qw(
f66d606b 30 Authentication
24ff036b 31 );
f66d606b 32
33 __PACKAGE__->config(
34 'authentication' => {
35 default_realm => "ldap",
36 realms => {
37 ldap => {
38 credential => {
39 class => "Password",
40 password_field => "password",
41 password_type => "self_check",
42 },
43 store => {
44 binddn => "anonymous",
45 bindpw => "dontcarehow",
46 class => "LDAP",
47 ldap_server => "ldap.yourcompany.com",
48 ldap_server_options => { timeout => 30 },
49 role_basedn => "ou=groups,ou=OxObjects,dc=yourcompany,dc=com",
50 role_field => "uid",
51 role_filter => "(&(objectClass=posixGroup)(memberUid=%s))",
52 role_scope => "one",
53 role_search_options => { deref => "always" },
54 role_value => "dn",
405489b5 55 role_search_as_user => 0,
f66d606b 56 start_tls => 1,
57 start_tls_options => { verify => "none" },
58 entry_class => "MyApp::LDAP::Entry",
59 use_roles => 1,
60 user_basedn => "ou=people,dc=yourcompany,dc=com",
61 user_field => "uid",
62 user_filter => "(&(objectClass=posixAccount)(uid=%s))",
57d476f1 63 user_scope => "one", # or "sub" for Active Directory
f66d606b 64 user_search_options => { deref => "always" },
1647b33a 65 user_results_filter => sub { return shift->pop_entry },
f66d606b 66 },
67 },
68 },
69 },
70 );
71
72 sub login : Global {
73 my ( $self, $c ) = @_;
74
75 $c->authenticate({
76 id => $c->req->param("login"),
77 password => $c->req->param("password")
78 });
79 $c->res->body("Welcome " . $c->user->username . "!");
80 }
81
82=head1 DESCRIPTION
83
84This plugin implements the L<Catalyst::Authentication> v.10 API. Read that documentation first if
85you are upgrading from a previous version of this plugin.
86
87This plugin uses C<Net::LDAP> to let your application authenticate against
88an LDAP directory. It has a pretty high degree of flexibility, given the
89wide variation of LDAP directories and schemas from one system to another.
90
91It authenticates users in two steps:
92
931) A search of the directory is performed, looking for a user object that
94 matches the username you pass. This is done with the bind credentials
95 supplied in the "binddn" and "bindpw" configuration options.
96
972) If that object is found, we then re-bind to the directory as that object.
98 Assuming this is successful, the user is Authenticated.
99
100=head1 CONFIGURATION OPTIONS
101
102=head2 Configuring with YAML
103
104Set Configuration to be loaded via Config.yml in YourApp.pm
105
106 use YAML qw(LoadFile);
107 use Path::Class 'file';
108
109 __PACKAGE__->config(
110 LoadFile(
111 file(__PACKAGE__->config->{home}, 'Config.yml')
112 )
113 );
114
115Settings in Config.yml (adapt these to whatever configuration format you use):
116
117 # Config for Store::LDAP
118 authentication:
119 default_realm: ldap
120 realms:
121 ldap:
122 credential:
123 class: Password
124 password_field: password
125 password_type: self_check
126 store:
127 class: LDAP
128 ldap_server: ldap.yourcompany.com
129 ldap_server_options:
130 timeout: 30
131 binddn: anonymous
132 bindpw: dontcarehow
133 start_tls: 1
134 start_tls_options:
135 verify: none
136 user_basedn: ou=people,dc=yourcompany,dc=com
137 user_filter: (&(objectClass=posixAccount)(uid=%s))
138 user_scope: one
139 user_field: uid
140 user_search_options:
141 deref: always
142 use_roles: 1
143 role_basedn: ou=groups,ou=OxObjects,dc=yourcompany,dc=com
144 role_filter: (&(objectClass=posixGroup)(memberUid=%s))
145 role_scope: one
146 role_field: uid
147 role_value: dn
148 role_search_options:
149 deref: always
150
151
152B<NOTE:> The settings above reflect the default values for OpenLDAP. If you
153are using Active Directory instead, Matija Grabnar suggests that the following
154tweeks to the example configuration will work:
155
156 user_basedn: ou=Domain Users,ou=Accounts,dc=mycompany,dc=com
157 user_field: samaccountname
158 user_filter: (sAMAccountName=%s)
57d476f1 159 user_scope: sub
f66d606b 160
161He also notes: "I found the case in the value of user_field to be significant:
162it didn't seem to work when I had the mixed case value there."
163
164=head2 ldap_server
165
166This should be the hostname of your LDAP server.
167
168=head2 ldap_server_options
169
170This should be a hashref containing options to pass to L<Net::LDAP>->new().
171See L<Net::LDAP> for the full list.
172
173=head2 binddn
174
175This should be the DN of the object you wish to bind to the directory as
176during the first phase of authentication. (The user lookup phase)
177
178If you supply the value "anonymous" to this option, we will bind anonymously
179to the directory. This is the default.
180
181=head2 bindpw
182
183This is the password for the initial bind.
184
185=head2 start_tls
186
187If this is set to 1, we will convert the LDAP connection to use SSL.
188
189=head2 start_tls_options
190
191This is a hashref, which contains the arguments to the L<Net::LDAP> start_tls
192method. See L<Net::LDAP> for the complete list of options.
193
194=head2 user_basedn
195
196This is the basedn for the initial user lookup. Usually points to the
197top of your "users" branch; ie "ou=people,dc=yourcompany,dc=com".
198
199=head2 user_filter
200
201This is the LDAP Search filter used during user lookup. The special string
202'%s' will be replaced with the username you pass to $c->login. By default
203it is set to '(uid=%s)'. Other possibly useful filters:
204
205 (&(objectClass=posixAccount)(uid=%s))
206 (&(objectClass=User)(cn=%s))
207
208=head2 user_scope
209
210This specifies the scope of the search for the initial user lookup. Valid
211values are "base", "one", and "sub". Defaults to "sub".
212
213=head2 user_field
214
215This is the attribute of the returned LDAP object we will use for their
216"username". This defaults to "uid". If you had user_filter set to:
217
218 (&(objectClass=User)(cn=%s))
219
220You would probably set this to "cn". You can also set it to an array,
221to allow more than one login field. The first field will be returned
222as identifier for the user.
223
224=head2 user_search_options
225
226This takes a hashref. It will append it's values to the call to
227L<Net::LDAP>'s "search" method during the initial user lookup. See
228L<Net::LDAP> for valid options.
229
230Be careful not to specify:
231
232 filter
233 scope
234 base
235
236As they are already taken care of by other configuration options.
237
1647b33a 238=head2 user_results_filter
239
240This is a Perl CODE ref that can be used to filter out multiple results
241from your LDAP query. In theory, your LDAP query should only return one result
242and find_user() will throw an exception if it encounters more than one result.
243However, if you have, for whatever reason, a legitimate reason for returning
244multiple search results from your LDAP query, use C<user_results_filter> to filter
245out the LDAP entries you do not want considered. Your CODE ref should expect
246a single argument, a Net::LDAP::Search object, and it should return exactly one
247value, a Net::LDAP::Entry object.
248
249Example:
250
251 user_results_filter => sub {
252 my $search_obj = shift;
253 foreach my $entry ($search_obj->entries) {
254 return $entry if my_match_logic( $entry );
255 }
256 return undef; # i.e., no match
257 }
258
f66d606b 259=head2 use_roles
260
261Whether or not to enable role lookups. It defaults to true; set it to 0 if
262you want to always avoid role lookups.
263
264=head2 role_basedn
265
266This should be the basedn where the LDAP Objects representing your roles are.
267
268=head2 role_filter
269
270This should be the LDAP Search filter to use during the role lookup. It
271defaults to '(memberUid=%s)'. The %s in this filter is replaced with the value
272of the "role_value" configuration option.
273
274So, if you had a role_value of "cn", then this would be populated with the cn
275of the User's LDAP object. The special case is a role_value of "dn", which
276will be replaced with the User's DN.
277
278=head2 role_scope
279
280This specifies the scope of the search for the user's role lookup. Valid
281values are "base", "one", and "sub". Defaults to "sub".
282
283=head2 role_field
284
285Should 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".
286
287=head2 role_value
288
289This is the attribute of the User object we want to use in our role_filter.
290If this is set to "dn", we will use the User Objects DN.
291
292=head2 role_search_options
293
294This takes a hashref. It will append it's values to the call to
295L<Net::LDAP>'s "search" method during the user's role lookup. See
296L<Net::LDAP> for valid options.
297
298Be careful not to specify:
299
300 filter
301 scope
302 base
303
304As they are already taken care of by other configuration options.
305
405489b5 306=head2 role_search_as_user
307
308By default this setting is false, and the role search will be performed
309by binding to the directory with the details in the I<binddn> and I<bindpw>
310fields. If this is set to false, then the role search will instead be
311performed when bound as the user you authenticated as.
312
313=head2 entry_class
314
315The name of the class of LDAP entries returned. This class should
316exist and is expected to be a subclass of Net::LDAP::Entry
317
318=head2 user_class
319
320The name of the class of user object returned. By default, this is
321L<Catalyst::Authentication::Store::LDAP::User>.
322
f66d606b 323=head1 METHODS
324
325=head2 new
326
327This method will populate
328L<Catalyst::Plugin::Authentication/default_auth_store> with this object.
329
330=head1 AUTHORS
331
332Adam Jacob <holoway@cpan.org>
333
334Some parts stolen shamelessly and entirely from
335L<Catalyst::Plugin::Authentication::Store::Htpasswd>.
336
337Currently maintained by Peter Karman <karman@cpan.org>.
338
339=head1 THANKS
340
341To nothingmuch, ghenry, castaway and the rest of #catalyst for the help. :)
342
343=head1 SEE ALSO
344
345L<Catalyst::Authentication::Store::LDAP>,
346L<Catalyst::Authentication::Store::LDAP::User>,
347L<Catalyst::Authentication::Store::LDAP::Backend>,
348L<Catalyst::Plugin::Authentication>,
349L<Net::LDAP>
350
351=head1 COPYRIGHT & LICENSE
352
353Copyright (c) 2005 the aforementioned authors. All rights
354reserved. This program is free software; you can redistribute
355it and/or modify it under the same terms as Perl itself.
356
357=cut
358
359