or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

auth-plugin.mdbasic-auth.mdbearer-auth.mddigest-auth.mdindex.md

digest-auth.mddocs/

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.