HTTP authentication support for multiple schemes including Basic, Bearer, Digest, and OAuth with header parsing, challenge generation, and parameter handling.
Constants for standard HTTP authentication schemes.
/**
* Standard HTTP authentication scheme constants
*/
object AuthScheme {
/** Basic authentication scheme */
const val Basic: String = "Basic"
/** Digest authentication scheme */
const val Digest: String = "Digest"
/** Negotiate/NTLM authentication scheme */
const val Negotiate: String = "Negotiate"
/** OAuth authentication scheme */
const val OAuth: String = "OAuth"
/** Bearer token authentication scheme */
const val Bearer: String = "Bearer"
}Base authentication header representation supporting both single token and parameterized authentication formats.
/**
* Base class for HTTP authentication headers
* @param authScheme the authentication scheme name
*/
sealed class HttpAuthHeader(val authScheme: String) {
/**
* Render authentication header with default encoding
* @return formatted header value string
*/
abstract fun render(): String
/**
* Render authentication header with specific encoding
* @param encoding the encoding to use for parameters
* @return formatted header value string
*/
abstract fun render(encoding: HeaderValueEncoding): String
}Authentication header containing a single token or blob.
/**
* Single token authentication header (e.g., Bearer, Basic)
* @param authScheme authentication scheme
* @param blob the authentication token/blob
*/
class Single(
authScheme: String,
val blob: String
) : HttpAuthHeader(authScheme) {
override fun render(): String
override fun render(encoding: HeaderValueEncoding): String
}Authentication header with named parameters (e.g., Digest, OAuth).
/**
* Parameterized authentication header with name-value pairs
* @param authScheme authentication scheme
* @param parameters list of authentication parameters
* @param encoding parameter encoding strategy
*/
class Parameterized(
authScheme: String,
val parameters: List<HeaderValueParam>,
val encoding: HeaderValueEncoding = HeaderValueEncoding.QUOTED_WHEN_REQUIRED
) : HttpAuthHeader(authScheme) {
/**
* Add a parameter to the authentication header
* @param name parameter name
* @param value parameter value
* @return new Parameterized header with added parameter
*/
fun withParameter(name: String, value: String): Parameterized
/**
* Replace an existing parameter or add if not present
* @param name parameter name
* @param value parameter value
* @return new Parameterized header with replaced parameter
*/
fun withReplacedParameter(name: String, value: String): Parameterized
/**
* Get parameter value by name
* @param name parameter name
* @return parameter value or null if not found
*/
fun parameter(name: String): String?
override fun render(): String
override fun render(encoding: HeaderValueEncoding): String
}Factory functions for creating common authentication challenges.
/**
* Create Basic authentication challenge
* @param realm authentication realm
* @param charset optional charset for encoding
* @return Parameterized authentication header
*/
fun HttpAuthHeader.Companion.basicAuthChallenge(
realm: String,
charset: Charset? = null
): Parameterized
/**
* Create Bearer authentication challenge
* @param scheme optional custom scheme name
* @param realm optional realm
* @return HttpAuthHeader for Bearer challenge
*/
fun HttpAuthHeader.Companion.bearerAuthChallenge(
scheme: String = AuthScheme.Bearer,
realm: String? = null
): HttpAuthHeader
/**
* Create Digest authentication challenge
* @param realm authentication realm
* @param nonce server nonce value
* @param domain optional domain
* @param opaque optional opaque value
* @param stale whether credentials are stale
* @param algorithm digest algorithm
* @return Parameterized authentication header
*/
fun HttpAuthHeader.Companion.digestAuthChallenge(
realm: String,
nonce: String,
domain: String? = null,
opaque: String? = null,
stale: Boolean? = null,
algorithm: String = "MD5"
): ParameterizedConstants for standard authentication parameter names.
/**
* Standard authentication parameter name constants
*/
object Parameters {
const val Realm: String = "realm"
const val Charset: String = "charset"
// OAuth parameters
const val OAuthCallback: String = "oauth_callback"
const val OAuthConsumerKey: String = "oauth_consumer_key"
const val OAuthNonce: String = "oauth_nonce"
const val OAuthToken: String = "oauth_token"
const val OAuthTokenSecret: String = "oauth_token_secret"
const val OAuthVerifier: String = "oauth_verifier"
const val OAuthSignatureMethod: String = "oauth_signature_method"
const val OAuthTimestamp: String = "oauth_timestamp"
const val OAuthVersion: String = "oauth_version"
const val OAuthSignature: String = "oauth_signature"
const val OAuthCallbackConfirmed: String = "oauth_callback_confirmed"
}Encoding strategies for authentication parameter values.
/**
* Parameter value encoding strategies
*/
enum class HeaderValueEncoding {
/** Quote only when required by value content */
QUOTED_WHEN_REQUIRED,
/** Always quote parameter values */
QUOTED_ALWAYS,
/** Use URI encoding for parameter values */
URI_ENCODE
}Functions for parsing authentication headers from strings.
/**
* Parse Authorization header value
* @param headerValue the Authorization header value
* @return HttpAuthHeader instance or null if invalid
*/
fun parseAuthorizationHeader(headerValue: String): HttpAuthHeader?
/**
* Parse multiple authentication headers from value
* @param headerValue header value containing multiple auth schemes
* @return list of HttpAuthHeader instances
*/
fun parseAuthorizationHeaders(headerValue: String): List<HttpAuthHeader>Usage Examples:
import io.ktor.http.auth.*
import io.ktor.http.*
// Create Basic authentication header
val basicAuth = HttpAuthHeader.Single(
AuthScheme.Basic,
"dXNlcjpwYXNzd29yZA==" // base64 encoded "user:password"
)
println(basicAuth.render()) // "Basic dXNlcjpwYXNzd29yZA=="
// Create Bearer token header
val bearerAuth = HttpAuthHeader.Single(
AuthScheme.Bearer,
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
)
println(bearerAuth.render()) // "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
// Create Digest authentication header
val digestAuth = HttpAuthHeader.Parameterized(
AuthScheme.Digest,
listOf(
HeaderValueParam("username", "testuser"),
HeaderValueParam("realm", "secure-area"),
HeaderValueParam("nonce", "abc123"),
HeaderValueParam("uri", "/protected"),
HeaderValueParam("response", "def456")
)
)
// Add parameters to digest auth
val updatedDigest = digestAuth
.withParameter("qop", "auth")
.withParameter("nc", "00000001")
// Get parameter values
val realm = digestAuth.parameter("realm") // "secure-area"
val username = digestAuth.parameter("username") // "testuser"
// Create authentication challenges
val basicChallenge = HttpAuthHeader.basicAuthChallenge(
realm = "Secure Area",
charset = Charsets.UTF_8
)
val bearerChallenge = HttpAuthHeader.bearerAuthChallenge(
realm = "api"
)
val digestChallenge = HttpAuthHeader.digestAuthChallenge(
realm = "Protected Area",
nonce = "dcd98b7102dd2f0e8b11d0f600bfb0c093",
algorithm = "MD5"
)
// Parse authentication headers
val authHeader = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
val parsed = parseAuthorizationHeader(authHeader)
when (parsed) {
is HttpAuthHeader.Single -> {
println("Scheme: ${parsed.authScheme}")
println("Token: ${parsed.blob}")
}
is HttpAuthHeader.Parameterized -> {
println("Scheme: ${parsed.authScheme}")
parsed.parameters.forEach { param ->
println("${param.name}: ${param.value}")
}
}
null -> println("Invalid authentication header")
}
// Parse multiple auth schemes
val multiAuthHeader = "Basic dXNlcjpwYXNz, Bearer token123"
val multiParsed = parseAuthorizationHeaders(multiAuthHeader)
multiParsed.forEach { auth ->
println("Found auth scheme: ${auth.authScheme}")
}
// Use different encoding strategies
val quotedAuth = HttpAuthHeader.Parameterized(
AuthScheme.Digest,
listOf(HeaderValueParam("response", "special=value")),
HeaderValueEncoding.QUOTED_ALWAYS
)
val uriEncodedAuth = HttpAuthHeader.Parameterized(
AuthScheme.OAuth,
listOf(HeaderValueParam("oauth_signature", "special%20chars")),
HeaderValueEncoding.URI_ENCODE
)
// OAuth example
val oauthAuth = HttpAuthHeader.Parameterized(
AuthScheme.OAuth,
listOf(
HeaderValueParam(Parameters.OAuthConsumerKey, "consumer123"),
HeaderValueParam(Parameters.OAuthToken, "token456"),
HeaderValueParam(Parameters.OAuthSignatureMethod, "HMAC-SHA1"),
HeaderValueParam(Parameters.OAuthTimestamp, "1234567890"),
HeaderValueParam(Parameters.OAuthNonce, "random123"),
HeaderValueParam(Parameters.OAuthVersion, "1.0"),
HeaderValueParam(Parameters.OAuthSignature, "signature789")
)
)/**
* Authentication parameter representation
* Already defined as HeaderValueParam in the main types section
*/