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
```