> ## Documentation Index
> Fetch the complete documentation index at: https://nestrs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# nestrs-ldap

> LDAP simple bind authentication for nestrs — NestJS passport-ldap analogue.

`nestrs-ldap` binds as `username` / `password` against a directory (`ldap3`). `Ok(())` means the server accepted the bind. Nest's `passport-ldap` strategy is the analogue.

## Install

```toml theme={null}
[dependencies]
nestrs = "1.3.0"
nestrs-ldap = "1.3.0"
```

## Bind

`{username}` in `bind_dn_template` is replaced with the login name:

```rust theme={null}
use nestrs_ldap::{LdapAuthOptions, LdapAuthenticator};

#[tokio::main]
async fn main() -> Result<(), nestrs_ldap::LdapAuthError> {
    let auth = LdapAuthenticator::new(LdapAuthOptions {
        url: "ldap://dc.example:389".into(),
        bind_dn_template: "cn={username},ou=people,dc=example,dc=com".into(),
    });

    auth.authenticate("ada", "s3cret").await?;
    Ok(())
}
```

From a login handler, map `LdapAuthError` to `401` when the bind fails:

```rust theme={null}
use nestrs::prelude::*;
use nestrs_ldap::{LdapAuthOptions, LdapAuthenticator};

#[derive(Default)]
#[injectable]
struct AppState;

#[controller(prefix = "/login")]
struct LoginController;

#[routes(state = AppState)]
impl LoginController {
    #[post("/")]
    async fn login(Json(body): Json<serde_json::Value>) -> Result<&'static str, (axum::http::StatusCode, String)> {
        let user = body["username"].as_str().unwrap_or("");
        let pass = body["password"].as_str().unwrap_or("");
        let auth = LdapAuthenticator::new(LdapAuthOptions {
            url: std::env::var("LDAP_URL").unwrap_or_else(|_| "ldap://127.0.0.1:389".into()),
            bind_dn_template: "cn={username},ou=people,dc=example,dc=com".into(),
        });
        auth.authenticate(user, pass)
            .await
            .map_err(|e| (axum::http::StatusCode::UNAUTHORIZED, e.to_string()))?;
        Ok("ok")
    }
}
```

Prefer `ldaps://` in production. This crate uses `ldap3` with default TLS features off at the crate level — enable TLS in your deployment (stunnel, `ldaps`, or a fork that turns ldap3 TLS on) if the directory requires it.

## API

| Type                                      | Role                     |
| ----------------------------------------- | ------------------------ |
| `LdapAuthOptions`                         | URL + bind DN template   |
| `LdapAuthenticator::new` / `authenticate` | Simple bind              |
| `LdapAuthError`                           | Wraps `ldap3::LdapError` |
