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