Ktor 1.6.8 Help

Form-based authentication

Form-based authentication uses a web form to collect credential information and authenticate a user.

Add dependencies

To enable form authentication, you need to include the ktor-auth artifact in the build script:

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

Form-based authentication flow

The form-based authentication flow might look as follows:

  1. An unauthenticated client makes a request to a specific route in a server application.

  2. A server returns an HTML page that consists at least from an HTML-based web form, which prompts a user for a username and password.

  3. When a user submits a username and password, a client makes a request containing web form data (which includes the username and password) to a server.

    POST http://localhost:8080/ Content-Type: application/x-www-form-urlencoded username=jetbrains&password=foobar

    In Ktor, you need to specify parameter names used to fetch a username and password.

  4. A server validates credentials sent by a client and responds with the requested content.

Install form authentication

To install the form authentication provider, call the form function inside the install block:

install(Authentication) { form { // Configure form authentication } }

You can optionally specify a provider name that can be used to authenticate a specified route.

Configure form authentication

Step 1: Configure a form provider

The form authentication provider exposes its settings via the FormAuthenticationProvider/Configuration class. In the example below, the following settings are specified:

  • The userParamName and passwordParamName properties specify parameter names used to fetch a username and password.

  • The validate function validates a username and password.

install(Authentication) { form("auth-form") { userParamName = "username" passwordParamName = "password" validate { credentials -> if(credentials.name == "jetbrains" && credentials.password == "foobar") { UserIdPrincipal(credentials.name) } else { null } } }

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

Step 2: Define authorization scope

After configuring the form provider, you can define the authorization for the different resources in our application using the authenticate function. In a 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-form") { post("/") { call.respondText("Hello, ${call.principal<UserIdPrincipal>()?.name}!") } } }
Last modified: 11 May 2022