or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcontent-types.mdcontent.mdcookies.mdheaders.mdhttp-core.mdindex.mdurls.md

authentication.mddocs/

0

# Authentication

1

2

HTTP authentication header parsing, challenge generation, and authentication scheme support.

3

4

## Capabilities

5

6

### HttpAuthHeader Base Class

7

8

Base class for all HTTP authentication headers with rendering support.

9

10

```kotlin { .api }

11

/**

12

* Base sealed class for HTTP authentication headers

13

* @param authScheme Authentication scheme (e.g., "Basic", "Bearer")

14

*/

15

sealed class HttpAuthHeader(val authScheme: String) {

16

17

/**

18

* Render header value using default encoding

19

* @return Header value string

20

*/

21

abstract fun render(): String

22

23

/**

24

* Render header value with specific encoding

25

* @param encoding Header value encoding mode

26

* @return Header value string

27

*/

28

abstract fun render(encoding: HeaderValueEncoding): String

29

30

companion object {

31

/**

32

* Create Basic authentication challenge

33

* @param realm Authentication realm

34

* @param charset Character set for credentials

35

* @return Parameterized auth header

36

*/

37

fun basicAuthChallenge(realm: String, charset: Charset): HttpAuthHeader.Parameterized

38

39

/**

40

* Create Digest authentication challenge

41

* @param realm Authentication realm

42

* @param nonce Server nonce value

43

* @param opaque Opaque value for client

44

* @param algorithm Hash algorithm (default MD5)

45

* @param stale Whether credentials are stale

46

* @param domain Protection domain

47

* @return Parameterized auth header

48

*/

49

fun digestAuthChallenge(

50

realm: String,

51

nonce: String,

52

opaque: String? = null,

53

algorithm: String? = null,

54

stale: Boolean? = null,

55

domain: String? = null

56

): HttpAuthHeader.Parameterized

57

58

/**

59

* Create Bearer authentication challenge

60

* @param realm Authentication realm (optional)

61

* @param scope Access scope (optional)

62

* @return Auth header

63

*/

64

fun bearerAuthChallenge(realm: String? = null, scope: String? = null): HttpAuthHeader

65

}

66

}

67

```

68

69

### Single Value Authentication

70

71

Authentication header with single value (e.g., Bearer token).

72

73

```kotlin { .api }

74

/**

75

* Authentication header with single value

76

* @param authScheme Authentication scheme

77

* @param blob Authentication value/token

78

*/

79

class HttpAuthHeader.Single(

80

authScheme: String,

81

val blob: String

82

) : HttpAuthHeader(authScheme) {

83

84

override fun render(): String

85

override fun render(encoding: HeaderValueEncoding): String

86

}

87

```

88

89

### Parameterized Authentication

90

91

Authentication header with parameters (e.g., Digest authentication).

92

93

```kotlin { .api }

94

/**

95

* Authentication header with parameters

96

* @param authScheme Authentication scheme

97

* @param parameters List of header parameters

98

* @param encoding Parameter value encoding

99

*/

100

class HttpAuthHeader.Parameterized(

101

authScheme: String,

102

val parameters: List<HeaderValueParam>,

103

val encoding: HeaderValueEncoding = HeaderValueEncoding.QUOTED_WHEN_REQUIRED

104

) : HttpAuthHeader(authScheme) {

105

106

constructor(

107

authScheme: String,

108

parameters: Map<String, String>,

109

encoding: HeaderValueEncoding = HeaderValueEncoding.QUOTED_WHEN_REQUIRED

110

)

111

112

/**

113

* Get parameter value by name

114

* @param name Parameter name

115

* @return Parameter value or null

116

*/

117

fun parameter(name: String): String?

118

119

/**

120

* Add parameter to existing header

121

* @param name Parameter name

122

* @param value Parameter value

123

* @return New Parameterized header with parameter

124

*/

125

fun withParameter(name: String, value: String): HttpAuthHeader.Parameterized

126

127

/**

128

* Replace existing parameter or add new one

129

* @param name Parameter name

130

* @param value Parameter value

131

* @return New Parameterized header with replaced parameter

132

*/

133

fun withReplacedParameter(name: String, value: String): HttpAuthHeader.Parameterized

134

135

override fun render(): String

136

override fun render(encoding: HeaderValueEncoding): String

137

}

138

```

139

140

### Authentication Schemes

141

142

Constants for common authentication schemes.

143

144

```kotlin { .api }

145

/**

146

* Common authentication schemes

147

*/

148

object AuthScheme {

149

val Basic: String

150

val Bearer: String

151

val Digest: String

152

val Negotiate: String

153

val OAuth: String

154

}

155

```

156

157

### Authentication Parameters

158

159

Constants for standard authentication parameters.

160

161

```kotlin { .api }

162

/**

163

* Standard authentication header parameters

164

*/

165

object HttpAuthHeader.Parameters {

166

val Realm: String

167

val Charset: String

168

169

// OAuth parameters

170

val OAuthCallback: String

171

val OAuthCallbackConfirmed: String

172

val OAuthConsumerKey: String

173

val OAuthNonce: String

174

val OAuthSignature: String

175

val OAuthSignatureMethod: String

176

val OAuthTimestamp: String

177

val OAuthToken: String

178

val OAuthTokenSecret: String

179

val OAuthVerifier: String

180

val OAuthVersion: String

181

}

182

```

183

184

### Header Value Encoding

185

186

Enumeration for different header value encoding modes.

187

188

```kotlin { .api }

189

/**

190

* Header value encoding modes

191

*/

192

enum class HeaderValueEncoding {

193

/**

194

* Quote values only when required by HTTP specification

195

*/

196

QUOTED_WHEN_REQUIRED,

197

198

/**

199

* Always quote parameter values

200

*/

201

QUOTED_ALWAYS,

202

203

/**

204

* URI encode parameter values

205

*/

206

URI_ENCODE

207

}

208

```

209

210

### Header Parsing Functions

211

212

Functions for parsing authentication headers from strings.

213

214

```kotlin { .api }

215

/**

216

* Parse Authorization header value

217

* @param headerValue Raw Authorization header value

218

* @return HttpAuthHeader instance or null if invalid

219

*/

220

fun parseAuthorizationHeader(headerValue: String): HttpAuthHeader?

221

222

/**

223

* Parse multiple Authorization headers

224

* @param headerValue Raw Authorization header value with multiple schemes

225

* @return List of HttpAuthHeader instances

226

*/

227

fun parseAuthorizationHeaders(headerValue: String): List<HttpAuthHeader>

228

```

229

230

**Usage Examples:**

231

232

```kotlin

233

import io.ktor.http.auth.*

234

import io.ktor.http.*

235

import java.nio.charset.StandardCharsets

236

237

// Create authentication headers

238

val basicAuth = HttpAuthHeader.Single(AuthScheme.Basic, "dXNlcjpwYXNz") // user:pass base64

239

val bearerAuth = HttpAuthHeader.Single(AuthScheme.Bearer, "eyJhbGciOiJIUzI1NiJ9...")

240

241

// Create parameterized authentication

242

val digestAuth = HttpAuthHeader.Parameterized(

243

AuthScheme.Digest,

244

listOf(

245

HeaderValueParam("realm", "Protected Area"),

246

HeaderValueParam("nonce", "abc123"),

247

HeaderValueParam("uri", "/api/data"),

248

HeaderValueParam("response", "def456")

249

)

250

)

251

252

// Create challenges for WWW-Authenticate header

253

val basicChallenge = HttpAuthHeader.basicAuthChallenge("Protected Area", StandardCharsets.UTF_8)

254

val digestChallenge = HttpAuthHeader.digestAuthChallenge(

255

realm = "Protected Area",

256

nonce = "abc123def456",

257

opaque = "xyz789"

258

)

259

val bearerChallenge = HttpAuthHeader.bearerAuthChallenge(

260

realm = "API Access",

261

scope = "read write"

262

)

263

264

// Render headers

265

val basicHeaderValue = basicAuth.render() // "Basic dXNlcjpwYXNz"

266

val bearerHeaderValue = bearerAuth.render() // "Bearer eyJhbGciOiJIUzI1NiJ9..."

267

val digestHeaderValue = digestAuth.render() // "Digest realm="Protected Area", nonce="abc123", ..."

268

269

// Parse headers

270

val parsed = parseAuthorizationHeader("Basic dXNlcjpwYXNz")

271

when (parsed) {

272

is HttpAuthHeader.Single -> println("Single auth: ${parsed.blob}")

273

is HttpAuthHeader.Parameterized -> println("Parameterized auth with ${parsed.parameters.size} params")

274

}

275

276

// Work with parameters

277

val realmParam = digestAuth.parameter("realm") // "Protected Area"

278

val withNewParam = digestAuth.withParameter("cnonce", "client123")

279

280

// Different encoding modes

281

val quoted = digestAuth.render(HeaderValueEncoding.QUOTED_ALWAYS)

282

val uriEncoded = digestAuth.render(HeaderValueEncoding.URI_ENCODE)

283

284

// Multiple authorization headers

285

val multipleHeaders = parseAuthorizationHeaders("Basic dXNlcjpwYXNz, Bearer token123")

286

println("Found ${multipleHeaders.size} auth headers")

287

288

// OAuth example

289

val oauthAuth = HttpAuthHeader.Parameterized(

290

AuthScheme.OAuth,

291

mapOf(

292

HttpAuthHeader.Parameters.OAuthConsumerKey to "consumer123",

293

HttpAuthHeader.Parameters.OAuthToken to "token456",

294

HttpAuthHeader.Parameters.OAuthSignatureMethod to "HMAC-SHA1",

295

HttpAuthHeader.Parameters.OAuthTimestamp to "1234567890",

296

HttpAuthHeader.Parameters.OAuthNonce to "nonce789",

297

HttpAuthHeader.Parameters.OAuthSignature to "signature="

298

)

299

)

300

301

// Build complete authentication flow

302

fun buildBasicAuth(username: String, password: String): String {

303

val credentials = "$username:$password"

304

val encoded = java.util.Base64.getEncoder().encodeToString(credentials.toByteArray())

305

return HttpAuthHeader.Single(AuthScheme.Basic, encoded).render()

306

}

307

308

fun buildBearerAuth(token: String): String {

309

return HttpAuthHeader.Single(AuthScheme.Bearer, token).render()

310

}

311

312

// Challenge responses

313

fun createBasicChallenge(realm: String): String {

314

return HttpAuthHeader.basicAuthChallenge(realm, StandardCharsets.UTF_8).render()

315

}

316

317

fun createDigestChallenge(realm: String, nonce: String): String {

318

return HttpAuthHeader.digestAuthChallenge(realm, nonce).render()

319

}

320

```