Authentication and authorization
Ktor provides the Auth
plugin (previously known as feature) to handle authentication and authorization in your client application. Typical usage scenarios include logging in users and gaining access to specific resources.
Supported authentication types
HTTP provides a general framework for access control and authentication. The Ktor client allows you to use the following HTTP authentication schemes:
Basic - uses
Base64
encoding to provide a username and password. Generally is not recommended if not used in combination with HTTPS.Digest - an authentication method that communicates user credentials in an encrypted form by applying a hash function to the username and password.
Bearer - an authentication scheme that involves security tokens called bearer tokens. For example, you can use this scheme as a part of OAuth flow to authorize users of your application by using external providers, such as Google, Facebook, Twitter, and so on.
Add dependencies
To enable authentication, you need to include the ktor-client-auth
artifact in the build script:
Install Auth
To install the Auth
plugin, pass it to the install
function inside a client configuration block:
Now you can configure the required authentication provider.
Configure authentication
Basic
The Basic authentication scheme can be used for logging in users. In this scheme, user credentials are transmitted as username/password pairs encoded using Base64. You can learn how the basic authentication flow might look from the Basic authentication flow section for a Ktor server.
To send user credentials in the Authorization
header using the Basic
scheme, you need to configure the basic
authentication provider as follows:
Call the basic function inside the
install
block.Provide the required credentials using BasicAuthCredentials and pass this object to the credentials function.
Optionally, configure the realm using the
realm
property.
You can find the full example here: client-auth-basic.
The client also allows you to send credentials in the initial request without waiting for a 401
(Unauthorized) response with the WWW-Authenticate
header. You need to call the sendWithoutRequest
function returning boolean and check the request parameters.
Digest
In the Digest authentication scheme, a hash function is applied to a username and password before sending them over the network. You can learn how the digest authentication flow might look from the Digest authentication flow section for a Ktor server.
To send user credentials in the Authorization
header using the Digest
scheme, you need to configure the digest
authentication provider as follows:
Call the digest function inside the
install
block.Provide the required credentials using DigestAuthCredentials and pass this object to the credentials function.
Optionally, configure the realm using the
realm
property.
You can find the full example here: client-auth-digest.
Bearer
Bearer authentication involves security tokens called bearer tokens. As an example, these tokens can be used as a part of OAuth flow to authorize users of your application by using external providers, such as Google, Facebook, Twitter, and so on.
A Ktor client allows you to configure a token to be sent in the Authorization
header using the Bearer
scheme. You can also specify logic for refreshing a token if the old one is invalid. To configure the bearer
provider, follow the steps below:
Call the bearer function inside the
install
block.Specify how to get an initial token using
loadTokens
. A code snippet below shows how to make a POST request to get the access and refresh tokens for accessing Google APIs.install(Auth) { lateinit var tokenInfo: TokenInfo var refreshTokenInfo: TokenInfo bearer { loadTokens { tokenInfo = tokenClient.submitForm( url = "https://accounts.google.com/o/oauth2/token", formParameters = Parameters.build { append("grant_type", "authorization_code") append("code", authorizationCode) append("client_id", clientId) append("redirect_uri", redirectUri) } ) BearerTokens( accessToken = tokenInfo.accessToken, refreshToken = tokenInfo.refreshToken!! ) } } }Specify how to obtain a new token if the old one is invalid using
refreshTokens
. Note that this block will be called after receiving a401
(Unauthorized) response with theWWW-Authenticate
header. The example below shows how to get a new access token using a refresh token.install(Auth) { lateinit var tokenInfo: TokenInfo var refreshTokenInfo: TokenInfo bearer { refreshTokens { unauthorizedResponse: HttpResponse -> refreshTokenInfo = tokenClient.submitForm( url = "https://accounts.google.com/o/oauth2/token", formParameters = Parameters.build { append("grant_type", "refresh_token") append("client_id", clientId) append("refresh_token", tokenInfo.refreshToken!!) } ) BearerTokens( accessToken = refreshTokenInfo.accessToken, refreshToken = tokenInfo.refreshToken!! ) } } }
After configuring the bearer
provider, you can make requests to the protected API.
You can find the full example here: client-auth-oauth-google.