Ktor 3.6.0 Help

LDAP

LDAP is a protocol for working with various directory services that can store information about users. Ktor allows you to authenticate LDAP users using the basic, digest, or form-based authentications schemes.

Add dependencies

To enable LDAP authentication, you need to include the ktor-server-auth and ktor-server-auth-ldap artifacts in the build script:

implementation("io.ktor:ktor-server-auth:$ktor_version") implementation("io.ktor:ktor-server-auth-ldap:$ktor_version")
implementation "io.ktor:ktor-server-auth:$ktor_version" implementation "io.ktor:ktor-server-auth-ldap:$ktor_version"
<dependency> <groupId>io.ktor</groupId> <artifactId>ktor-server-auth</artifactId> <version>${ktor_version}</version> </dependency> <dependency> <groupId>io.ktor</groupId> <artifactId>ktor-server-auth-ldap</artifactId> <version>${ktor_version}</version> </dependency>

Configure LDAP

Step 1: Choose an authentication provider

To authenticate LDAP users, you first need to choose an authentication provider for username and password validation. In Ktor, the basic, digest, or form-based providers can be used for this. For example, to use the basic authentication provider, call the basic function inside the install block.

import io.ktor.server.application.* import io.ktor.server.auth.* import io.ktor.server.auth.ldap.* //... install(Authentication) { basic { validate { credentials -> // Authenticate an LDAP user } } }

The validate function will be used to check user credentials.

Step 2: Authenticate an LDAP user

To authenticate an LDAP user, you need to call the ldapAuthenticate function. This function accepts UserPasswordCredential and validates it against a specified LDAP server.

install(Authentication) { basic("auth-ldap") { validate { credentials -> val url = "ldap://0.0.0.0:389" val userDNFormat = "cn=%s,dc=ktor,dc=io" ldapAuthenticate(credentials, url, userDNFormat) } } }

The validate function returns a UserIdPrincipal in the case of successful authentication or null if authentication fails.

Optionally, you can add additional validation for an authenticated user.

install(Authentication) { basic("auth-ldap") { validate { credentials -> val url = "ldap://localhost:389" val userDNFormat = "cn=%s,dc=ktor,dc=io" ldapAuthenticate(credentials, url, userDNFormat) { if (it.name == it.password) { UserIdPrincipal(it.name) } else { null } } } } }

There is no LDAP-specific type-safe authentication scheme. Call ldapAuthenticate inside the validate block of a type-safe basic, digest, or form scheme.

Pass a block to ldapAuthenticate to return your own principal type:

data class User(val name: String) val ldapAuth = basic<User>("auth-ldap") { validate { credentials -> val url = "ldap://0.0.0.0:389" val userDNFormat = "cn=%s,dc=ktor,dc=io" ldapAuthenticate(credentials, url, userDNFormat) { User(it.name) } } }

The block also lets you add validation for an authenticated user:

val ldapAuth = basic<User>("auth-ldap") { validate { credentials -> val url = "ldap://localhost:389" val userDNFormat = "cn=%s,dc=ktor,dc=io" ldapAuthenticate(credentials, url, userDNFormat) { if (it.name == it.password) { User(it.name) } else { null } } } }

For the full API, see Type-safe authentication.

Step 3: Protect specific resources

After configuring LDAP, you can protect specific resources in our application using the authenticate function. In the case of successful authentication, you can retrieve an authenticated UserIdPrincipal inside a route handler using the call.principal function and get a name of an authenticated user.

routing { authenticate("auth-ldap") { get("/") { val user = call.principal<UserIdPrincipal>() call.respondText("Hello, ${user?.name}!") } } }

Pass the scheme to authenticateWith(). Inside the block, call.principal is your principal type and is never null, so no cast or null check is needed:

routing { authenticateWith(ldapAuth) { get("/") { call.respondText("Hello, ${call.principal.name}!") } } }

You can find the complete runnable example here: auth-ldap.

14 September 2026