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 <holoway@cpan.org>

    Some parts stolen shamelessly and entirely from
    Catalyst::Plugin::Authentication::Store::Htpasswd.

    Currently maintained by Peter Karman <karman@cpan.org>.

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.

