0
# Digest Authentication
1
2
Challenge-response authentication using HTTP Digest authentication scheme. Provides improved security over Basic auth by using cryptographic hashes instead of plain text credentials.
3
4
## Capabilities
5
6
### Digest Provider Installation
7
8
Install Digest authentication with credential and algorithm configuration.
9
10
```kotlin { .api }
11
/**
12
* Install Digest authentication provider
13
* @param block Configuration block for DigestAuthConfig
14
*/
15
fun AuthConfig.digest(block: DigestAuthConfig.() -> Unit)
16
```
17
18
**Usage Example:**
19
20
```kotlin
21
install(Auth) {
22
digest {
23
credentials {
24
// Load from secure storage
25
val creds = credentialStorage.getDigestCredentials()
26
DigestAuthCredentials(creds.username, creds.password)
27
}
28
29
algorithmName = "MD5" // Default hash algorithm
30
realm = "Protected Area" // Optional realm restriction
31
}
32
}
33
```
34
35
### DigestAuthCredentials Class
36
37
Container for Digest authentication credentials.
38
39
```kotlin { .api }
40
/**
41
* Container for digest authentication credentials
42
* @param username The username for authentication
43
* @param password The password for authentication (used for hash computation)
44
*/
45
class DigestAuthCredentials(
46
val username: String,
47
val password: String
48
)
49
```
50
51
### DigestAuthConfig Class
52
53
Configuration for Digest authentication provider.
54
55
```kotlin { .api }
56
/**
57
* Configuration for Digest authentication
58
*/
59
class DigestAuthConfig {
60
/**
61
* Hash algorithm for digest computation (default: "MD5")
62
*/
63
var algorithmName: String
64
65
/**
66
* Optional realm restriction for this provider
67
*/
68
var realm: String?
69
70
/**
71
* Configure callback to load authentication credentials
72
* @param block Function that returns credentials or null
73
*/
74
fun credentials(block: suspend () -> DigestAuthCredentials?)
75
}
76
```
77
78
### DigestAuthProvider Class
79
80
Implementation of Digest authentication provider with challenge-response handling.
81
82
```kotlin { .api }
83
/**
84
* Digest authentication provider implementation
85
*/
86
class DigestAuthProvider(
87
private val credentials: suspend () -> DigestAuthCredentials?,
88
val realm: String? = null,
89
val algorithmName: String = "MD5"
90
) : AuthProvider {
91
/**
92
* Clear cached credentials from memory
93
* Call when credentials are updated or during logout
94
* Note: This is an internal API and may change in future versions
95
*/
96
@InternalAPI
97
fun clearToken()
98
}
99
```
100
101
## Authentication Flow
102
103
### Challenge-Response Process
104
105
1. **Initial Request**: Client makes request without authentication
106
2. **401 Challenge**: Server responds with WWW-Authenticate header containing nonce and other parameters
107
3. **Response Calculation**: Client computes digest using credentials and challenge parameters
108
4. **Authenticated Request**: Client retries with Authorization header containing computed digest
109
110
### Digest Computation
111
112
The digest is calculated using this process:
113
114
```
115
HA1 = MD5(username:realm:password)
116
HA2 = MD5(method:uri)
117
response = MD5(HA1:nonce:nc:cnonce:qop:HA2)
118
```
119
120
Where:
121
- `nonce`: Random value from server challenge
122
- `nc`: Request counter (hexadecimal, zero-padded to 8 digits)
123
- `cnonce`: Client-generated random value
124
- `qop`: Quality of protection (from server challenge)
125
126
### Challenge Parameters
127
128
Digest authentication handles these WWW-Authenticate parameters:
129
130
- **realm**: Authentication realm (required)
131
- **nonce**: Server-generated random value (required)
132
- **qop**: Quality of protection (optional)
133
- **opaque**: Server-specific data (optional)
134
- **algorithm**: Hash algorithm, defaults to MD5
135
136
**Example Challenge:**
137
```
138
WWW-Authenticate: Digest realm="Protected Area",
139
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
140
qop="auth",
141
opaque="5ccc069c403ebaf9f0171e9517f40e41"
142
```
143
144
## Usage Examples
145
146
### Simple Digest Authentication
147
148
```kotlin
149
install(Auth) {
150
digest {
151
credentials {
152
DigestAuthCredentials("user", "password")
153
}
154
}
155
}
156
```
157
158
### Advanced Configuration
159
160
```kotlin
161
install(Auth) {
162
digest {
163
credentials {
164
// Load from secure configuration
165
val config = loadSecureConfig()
166
DigestAuthCredentials(
167
username = config.digestUsername,
168
password = config.digestPassword
169
)
170
}
171
172
algorithmName = "SHA-256" // Use stronger algorithm if supported
173
realm = "API Access" // Restrict to specific realm
174
}
175
}
176
```
177
178
### Multiple Digest Providers
179
180
```kotlin
181
install(Auth) {
182
// Admin realm
183
digest {
184
credentials { getAdminDigestCredentials() }
185
realm = "Admin"
186
}
187
188
// User realm
189
digest {
190
credentials { getUserDigestCredentials() }
191
realm = "User"
192
algorithmName = "SHA-256"
193
}
194
}
195
```
196
197
## Security Features
198
199
### Improved Security over Basic Auth
200
201
- **No Plain Text**: Password is never sent over network
202
- **Nonce Protection**: Server nonce prevents replay attacks
203
- **Request Counting**: nc parameter prevents replay attacks
204
- **Client Nonce**: cnonce adds additional randomness
205
206
### Hash Algorithms
207
208
Supported algorithms (server dependent):
209
- **MD5**: Default, widely supported but cryptographically weak
210
- **SHA-256**: Stronger hash function, better security
211
- **SHA-512**: Even stronger, limited server support
212
213
### Quality of Protection (QOP)
214
215
- **auth**: Authentication only (default)
216
- **auth-int**: Authentication with integrity protection (includes request body hash)
217
218
## Request Counter Management
219
220
The provider automatically manages request counters:
221
222
- Each provider maintains an atomic counter
223
- Counter increments with each authenticated request
224
- Counter value is formatted as 8-digit hexadecimal
225
- Prevents replay attacks when used with nonces
226
227
## Error Scenarios
228
229
- **Missing Nonce**: Provider rejects challenges without nonce parameter
230
- **Missing Realm**: Provider rejects challenges without realm parameter
231
- **Realm Mismatch**: Provider ignores challenges for different realms
232
- **Invalid Credentials**: Server returns 401/403 for incorrect digest
233
- **Unsupported Algorithm**: Provider defaults to MD5 if algorithm unsupported
234
235
## Limitations
236
237
- **Server Support**: Not all servers support Digest authentication
238
- **Algorithm Negotiation**: Limited algorithm support across servers
239
- **Performance**: Hash computation adds processing overhead
240
- **No Token Refresh**: No automatic credential refresh mechanism
241
- **MD5 Weakness**: Default MD5 algorithm has known cryptographic weaknesses
242
243
## Security Considerations
244
245
- **Use HTTPS**: While more secure than Basic auth, HTTPS is still recommended
246
- **Strong Passwords**: Password strength is critical since it's used in hash computation
247
- **Algorithm Choice**: Use SHA-256 or stronger when server supports it
248
- **Credential Storage**: Store credentials securely using platform-specific secure storage
249
- **Session Management**: Clear credentials on logout or session expiration
250
251
## Migration from Basic Auth
252
253
To migrate from Basic to Digest authentication:
254
255
```kotlin
256
// Before: Basic Auth
257
install(Auth) {
258
basic {
259
credentials { BasicAuthCredentials("user", "pass") }
260
}
261
}
262
263
// After: Digest Auth
264
install(Auth) {
265
digest {
266
credentials { DigestAuthCredentials("user", "pass") }
267
algorithmName = "SHA-256" // Upgrade algorithm if possible
268
}
269
}
270
```
271
272
No code changes needed in request handling - the provider handles all digest computation automatically.