0
# Basic Authentication
1
2
HTTP Basic authentication implementation that validates username and password credentials sent in the `Authorization` header. This provider extracts credentials from the HTTP Basic authentication scheme and validates them using a custom authentication function.
3
4
## Configuration
5
6
```kotlin { .api }
7
fun AuthenticationConfig.basic(
8
name: String? = null,
9
configure: BasicAuthenticationProvider.Config.() -> Unit
10
)
11
12
@KtorDsl
13
class BasicAuthenticationProvider.Config(name: String?) : AuthenticationProvider.Config(name) {
14
var realm: String
15
var charset: Charset?
16
fun validate(body: suspend ApplicationCall.(UserPasswordCredential) -> Any?)
17
fun challenge(body: ChallengeFunction)
18
fun skipWhen(predicate: ApplicationCallPredicate)
19
}
20
```
21
22
### Configuration Properties
23
24
- **`realm`**: The authentication realm displayed to users (default: "Ktor Server")
25
- **`charset`**: Character encoding for credential parsing (default: UTF-8)
26
27
### Configuration Functions
28
29
- **`validate`**: Suspend function that validates credentials and returns a principal
30
- **`challenge`**: Custom challenge function for authentication failures
31
- **`skipWhen`**: Predicate to skip authentication for certain calls
32
33
## Basic Usage
34
35
```kotlin
36
install(Authentication) {
37
basic("auth-basic") {
38
realm = "Access to protected resources"
39
validate { credentials ->
40
if (credentials.name == "admin" && credentials.password == "secret") {
41
UserIdPrincipal(credentials.name)
42
} else {
43
null
44
}
45
}
46
}
47
}
48
49
routing {
50
authenticate("auth-basic") {
51
get("/admin") {
52
val principal = call.principal<UserIdPrincipal>()
53
call.respond("Welcome ${principal?.name}!")
54
}
55
}
56
}
57
```
58
59
## Advanced Configuration
60
61
### Custom Challenge Response
62
63
```kotlin
64
basic("auth-basic") {
65
realm = "Secure Area"
66
validate { credentials ->
67
// Validate against database
68
userService.authenticate(credentials)
69
}
70
challenge { defaultScheme, realm ->
71
call.respond(
72
UnauthorizedResponse(
73
HttpAuthHeader.basicAuthChallenge(realm)
74
)
75
)
76
}
77
}
78
```
79
80
### Using Hashed Password Table
81
82
```kotlin
83
val hashedUserTable = UserHashedTableAuth(
84
table = mapOf(
85
"admin" to decodeBase64("password_hash"),
86
"user" to decodeBase64("another_hash")
87
),
88
digester = getDigestFunction("SHA-256") { "ktor${it.length}" }
89
)
90
91
basic("auth-basic") {
92
realm = "Protected Area"
93
validate { credentials ->
94
hashedUserTable.authenticate(credentials)
95
}
96
}
97
```
98
99
## API Reference
100
101
### Provider Class
102
103
```kotlin { .api }
104
class BasicAuthenticationProvider internal constructor(
105
config: Config
106
) : AuthenticationProvider(config)
107
108
abstract class AuthenticationProvider(config: Config) {
109
abstract suspend fun onAuthenticate(context: AuthenticationContext)
110
111
open class Config(val name: String?) {
112
fun skipWhen(predicate: ApplicationCallPredicate)
113
}
114
}
115
```
116
117
### Credential Extraction
118
119
```kotlin { .api }
120
fun ApplicationRequest.basicAuthenticationCredentials(charset: Charset? = null): UserPasswordCredential?
121
```
122
123
### Authentication Function Type
124
125
```kotlin { .api }
126
typealias AuthenticationFunction<C> = suspend ApplicationCall.(C) -> Any?
127
```
128
129
### Challenge Function Type
130
131
```kotlin { .api }
132
typealias ChallengeFunction = suspend PipelineContext<*, ApplicationCall>.(
133
defaultScheme: String,
134
realm: String
135
) -> Unit
136
```
137
138
## Common Integration Patterns
139
140
### Database Integration
141
142
```kotlin
143
basic("database-auth") {
144
realm = "Database Protected"
145
validate { credentials ->
146
transaction {
147
Users.select { Users.username eq credentials.name }
148
.singleOrNull()
149
?.let { user ->
150
if (BCrypt.checkpw(credentials.password, user[Users.passwordHash])) {
151
UserIdPrincipal(credentials.name)
152
} else null
153
}
154
}
155
}
156
}
157
```
158
159
### Multiple Authentication Schemes
160
161
```kotlin
162
// Allow both basic and bearer authentication
163
authenticate("auth-basic", "auth-bearer", strategy = AuthenticationStrategy.FirstSuccessful) {
164
get("/api/data") {
165
// Handle authenticated request
166
}
167
}
168
```
169
170
## Error Handling
171
172
Basic authentication failures are handled through the challenge system:
173
174
```kotlin { .api }
175
sealed class AuthenticationFailedCause {
176
object NoCredentials : AuthenticationFailedCause()
177
object InvalidCredentials : AuthenticationFailedCause()
178
class Error(val message: String) : AuthenticationFailedCause()
179
}
180
```
181
182
The provider automatically returns appropriate HTTP status codes:
183
- **401 Unauthorized**: When credentials are invalid or missing
184
- **403 Forbidden**: When authentication succeeds but authorization fails
185
186
## Security Considerations
187
188
- Basic authentication transmits credentials in Base64 encoding (not encryption)
189
- Always use HTTPS in production to protect credentials in transit
190
- Consider rate limiting to prevent brute force attacks
191
- Store passwords using secure hashing algorithms (bcrypt, scrypt, etc.)
192
- Validate input to prevent injection attacks