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