CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-ktor--ktor-client-auth

Ktor client authentication and authorization plugin that handles various authentication schemes including Basic, Bearer, and Digest authentication.

Pending
Overview
Eval results
Files

bearer-auth.mddocs/

Bearer Authentication

OAuth2/JWT token authentication with automatic token refresh and management. Ideal for API authentication with access tokens and optional refresh tokens.

Capabilities

Bearer Provider Installation

Install Bearer authentication with token loading and refresh configuration.

/**
 * Install Bearer authentication provider
 * @param block Configuration block for BearerAuthConfig
 */
fun AuthConfig.bearer(block: BearerAuthConfig.() -> Unit)

Usage Example:

install(Auth) {
    bearer {
        loadTokens {
            // Load from secure storage
            val tokens = tokenStorage.getTokens()
            BearerTokens(tokens.accessToken, tokens.refreshToken)
        }
        
        refreshTokens { params ->
            // Call refresh endpoint
            val response = authClient.post("/oauth/refresh") {
                setBody(RefreshRequest(params.oldTokens?.refreshToken))
            }
            val newTokens = response.body<TokenResponse>()
            BearerTokens(newTokens.accessToken, newTokens.refreshToken)
        }
        
        sendWithoutRequest { request ->
            // Send tokens proactively for API calls
            request.url.host == "api.example.com"
        }
        
        realm = "api" // Optional realm restriction
    }
}

BearerTokens Class

Container for Bearer authentication tokens.

/**
 * Container for bearer tokens
 * @param accessToken The access token for API requests
 * @param refreshToken Optional refresh token for obtaining new access tokens
 */
class BearerTokens(
    val accessToken: String,
    val refreshToken: String?
)

BearerAuthConfig Class

Configuration for Bearer authentication provider.

/**
 * Configuration for Bearer authentication
 */
class BearerAuthConfig {
    /**
     * Optional realm restriction for this provider
     */
    var realm: String?
    
    /**
     * Configure callback to load cached tokens from storage
     * Note: Using the same client instance here will result in deadlock
     * @param block Function that returns cached tokens or null
     */
    fun loadTokens(block: suspend () -> BearerTokens?)
    
    /**
     * Configure callback to refresh tokens when 401 is received
     * @param block Function that receives refresh parameters and returns new tokens
     */
    fun refreshTokens(block: suspend RefreshTokensParams.() -> BearerTokens?)
    
    /**
     * Configure when to send credentials without waiting for 401
     * @param block Function that returns true if credentials should be sent preemptively
     */
    fun sendWithoutRequest(block: (HttpRequestBuilder) -> Boolean)
}

RefreshTokensParams Class

Parameters provided to the token refresh callback.

/**
 * Parameters for token refresh callback
 */
class RefreshTokensParams(
    val client: HttpClient,
    val response: HttpResponse,
    val oldTokens: BearerTokens?
) {
    /**
     * Mark refresh request to prevent authentication loops
     */
    fun HttpRequestBuilder.markAsRefreshTokenRequest()
}

Usage Example:

refreshTokens { params ->
    // Use the provided client to make refresh request
    val refreshRequest = HttpRequestBuilder().apply {
        markAsRefreshTokenRequest() // Prevent auth loop
        method = HttpMethod.Post
        url("https://auth.example.com/refresh")
        setBody(params.oldTokens?.refreshToken)
    }
    
    val response = params.client.request(refreshRequest)
    if (response.status.isSuccess()) {
        val tokenData = response.body<TokenResponse>()
        BearerTokens(tokenData.accessToken, tokenData.refreshToken)
    } else {
        null // Refresh failed
    }
}

BearerAuthProvider Class

Implementation of Bearer authentication provider.

/**
 * Bearer authentication provider implementation
 */
class BearerAuthProvider(
    private val refreshTokens: suspend RefreshTokensParams.() -> BearerTokens?,
    loadTokens: suspend () -> BearerTokens?,
    private val sendWithoutRequestCallback: (HttpRequestBuilder) -> Boolean = { true },
    private val realm: String?
) : AuthProvider {
    /**
     * Clear cached tokens from memory
     * Call when tokens are updated externally or during logout
     */
    fun clearToken()
}

Token Management

The Bearer provider includes sophisticated token management:

Automatic Header Addition

When tokens are available, the provider automatically adds the Authorization header:

Authorization: Bearer <access_token>

Token Caching

  • Tokens are cached in memory after first load
  • loadTokens is called only when cache is empty
  • clearToken() forces reload on next request

Refresh Logic

  1. When 401 response is received, refreshTokens callback is invoked
  2. If refresh succeeds, new tokens are cached and request retried
  3. If refresh fails, original 401 response is returned
  4. Refresh requests are automatically marked with circuit breaker

Realm Handling

If a realm is specified in configuration:

  • Provider only applies to WWW-Authenticate headers with matching realm
  • Multiple Bearer providers can coexist with different realms

Error Scenarios

  • Load Tokens Failure: Request proceeds without authentication if loadTokens returns null
  • Refresh Failure: Original 401 response returned if refreshTokens returns null
  • Network Errors: Refresh failures due to network issues return original response
  • Invalid Tokens: Malformed or expired tokens trigger refresh attempt

Security Considerations

  • Store tokens securely using platform-specific secure storage
  • Use HTTPS for all token-related requests
  • Implement proper token expiration handling
  • Clear tokens on logout or app termination
  • Avoid logging token values in production

Install with Tessl CLI

npx tessl i tessl/maven-io-ktor--ktor-client-auth

docs

auth-plugin.md

basic-auth.md

bearer-auth.md

digest-auth.md

index.md

tile.json