Hi Joan,

Yes, I'm planning to maintain it, and hopefully it's readable enough for
others to do so if necessary. In any case, since current Cloudant Local
customers are being encouraged (with few on-prem alternatives) to migrate
to CouchDB, there should be a built-in user base for as well. This is
definitely not abandonware!

And, yes, I'm still planning to get weatherreport into 3.2 as well. Thanks
for the encouragement :)

Jay

On Tue, Sep 1, 2020 at 1:42 PM Joan Touzet <woh...@apache.org> wrote:

> I remember this code!
>
> Sure, let's get it out there, *as long as* someone is going to maintain
> it going forward.
>
> I had been hoping to see more rallying behind how to use the JWT
> integration for OAuth and SAML workflows, but no one's done any
> walkthroughs / blogposts that I've seen. Putting those things in front
> of LDAP may be easier (but would be outside the scope of CouchDB...)
>
> While we're on the topic of donation, any chance of weatherreport
> getting donated? You had brought this up a few months ago, Jay, and I'd
> love to see that in 3.2 as well.
>
> -Joan
>
>
>
> On 2020-09-01 3:02 p.m., Jay Doane wrote:
> > Greetings,
> >
> > In 2015 IBM Cloudant developed an LDAP based authentication handler for
> > its CouchDB 2.x-based Cloudant Local offering. Since then, it has been
> used
> > in production on several large Cloudant Local deployments, accruing many
> > bug fixes and enhancements in the process.
> >
> > Over the years, there has clearly been interest in using LDAP with
> CouchDB
> > [1], so it seems like the ldap_auth functionality might be something the
> > greater community could benefit from. If there are no objections from the
> > community or PMC, I'd be happy to open a PR in the hopes of getting it
> > included in CouchDB 3.2. To give an idea of what it's all about, I've
> > included the README.md contents below.
> >
> > Thanks,
> > Jay
> >
> > [1] https://couchdb.markmail.org/search/?q=LDAP
> >
> > README.md:
> >
> > # Delegating Basic and Cookie authentication and authorization to LDAP
> >
> > CouchDB includes a built-in security model, with self-contained
> > authentication and authorization which rely on .ini files and/or user
> > databases to store user data, including usernames (uids), password
> > hashes, and user roles for accessing database resources.
> >
> > For an organization which already uses an LDAP service for access
> > control, it may make more sense to delegate authentication and
> > authorization services to LDAP when accessing CouchDB. This is where
> > `ldap_auth` comes in.
> >
> > At a high level, when `ldap_auth` is configured, it completely
> > replaces the default Basic and Cookie authentication and
> > authorization. It ignores .ini files and user databases altogether,
> > and attempts to validate user credentials using the configured LDAP
> > service. Once credentials have been authentication by the LDAP
> > service, `ldap_auth` determines the user's roles (which in turn
> > determine what the user is authorized to access) based on the LDAP
> > groups of which the user is a member.
> >
> > ## ldap_interface
> >
> > This low-level interface module uses
> > [eldap](http://www.erlang.org/doc/man/eldap.html) to connect to,
> > authenticate, and search LDAP server(s) which are configured to model
> > user accounts and their associated CouchDB roles.
> >
> > ### Configuration
> >
> > All configuration is done via `.ini` file, mostly in the `[ldap_auth]`
> > section. The following parameters can be modified, and have the
> > associated defaults in parentheses:
> >
> > - `servers (127.0.0.1)` one or more LDAP servers; defaults to a single
> > host, but could be a comma separated list (note that all servers must
> > use the same port, a limitation of the underlying eldap library)
> >
> > - `port (389)` LDAP server port for un-encrypted communication
> >
> > - `ssl_port (636)` LDAP server port for encrypted communication
> >
> > - `use_ssl (true)` if `true`, use TLS to encrypt traffic to LDAP
> > servers
> >
> > - `timeout (5000)` milliseconds to wait for a response from an LDAP
> > server before throwing an error
> >
> > - `user_base_dn (ou=users,dc=example,dc=com)` defines a directory
> > location to start searching for users
> >
> > - `user_classes (person)` defines which `objectClass`es indicate
> > a particular entry as a user during search
> >
> > - `user_uid_attribute (uid)` defines which attribute maps to
> > username
> >
> > - `group_base_dn (ou=groups,dc=example,dc=com)` defines directory
> > location to start searching for groups
> >
> > - `group_classes (posixGroup)` defines which `objectClass`es indicate
> > a particular entry as a group during search
> >
> > - `group_member_attribute (memberUid)` defines which group attribute
> > maps to user Uid
> >
> > - `group_role_attribute (description)` defines which group attribute
> > maps to a particular role
> >
> > - `searcher_dn (uid=ldapsearch,ou=users,dc=example,dc=com)` defines
> > the DN to use when searching for users and groups
> >
> > - `searcher_password (secret)` defines the password for the
> > `searcher_dn` above
> >
> > - `user_bind_dns ([])` defines one or more base DNs into which the
> > authenticating user's username can be inserted as the
> > `user_uid_attribute`, and used to bind directly. See the "Efficiency
> > Considerations" section below for details
> >
> > **Please note** that at least one of the above parameters must be set
> > inside the `[ldap_auth]` section of a .ini configuration file in order
> > for ldap_auth to be considered "configured", and to function as an
> > authentication/authorization handler. Failure to explicitly set at
> > least one `[ldap_auth]` parameter will result in the system using the
> > default basic and cookie authentication/authorization handlers instead.
> >
> > ### Efficiency Considerations
> >
> >    `ldap_auth` effectively has 2 modes of operation, depending on
> > whether `user_bind_dns` has been defined or not. Both modes return a
> > list of roles associated with a user upon authentication success.
> >
> >    By default, `ldap_auth` opens a connection to an LDAP server and
> > binds the connection handle with the searcher DN and password. It then
> > uses that connection to search for a user record with the
> > authenticating username. If a matching user DN is found, it opens a
> > second connection to the server and attempts to bind that connection
> > using the username and password credentials. If the bind is
> > successful, it closes that connection, and uses the original
> > "searcher" bound connection to search for groups which contain the
> > `group_member_attribute` matching the user's username. Those groups
> > have a `group_role_attribute` which indicates the actual roles for the
> > user.
> >
> >    On the other hand, if you know in advance that all your users' DNs
> > can be constructed by inserting their usernames into the following
> > pattern: `$uid_attribute=$username,$user_bind_dn`
> > (e.g. `uid=jay,ou=users,dc=example,dc=com`), then you can configure
> > one or more `user_bind_dns`, and `ldap_auth` will not make use of the
> > searcher DN, nor `user_base_dn`, but instead attempt to bind directly
> > with the constructed user DNs. If the bind is successful, that bound
> > connection is further used to make the same group search as described
> > in the above paragraph. Overall, this technique can be used to
> > eliminate several additional network round trips.
> >
> > ## ldap_auth
> >
> >    Implements Basic and Cookie based authentication handlers, using
> > `ldap_interface:authorized_roles(Username, Password)` to obtain the
> > roles associated with a particular user.
> >
> >    Using `ldap_auth` with basic authentication requires no client side
> > changes. A properly configured database will automatically attempt to
> > authenticate via LDAP using the supplied credentials.
> >
> >    Similarly, for cookie authentication, POST credentials to the
> > `_session` endpoint to obtain an AuthSession cookie, which contains a
> > signed hash of its contents: name, time issued, and authorized
> > roles. Subsequent requests using that cookie will automatically use
> > the roles in the cookie until it expires. The following configuration
> > parameters in the `[couch_httpd_auth]` section are used:
> >
> > - `timeout (600)` seconds until the AuthSession cookie expires
> >
> > - `secret` the shared secret used to sign the AuthSession cookie,
> > it should be created when the cluster is provisioned
> >
>

Reply via email to