private fun validator():
suspend ApplicationCall.(UserPasswordCredential) -> Principal? =
{ credentials ->
if ( userList.find {
it.username == credentials.name
}?.password == credentials.password
){
UserIdPrincipal(credentials.name) }
else { null }
}
install(Authentication) {
basic("auth-basic") {
realm = "Access to the '/basic' path"
validate(validator())
}
}
routing {
authenticate("auth-basic") {
get("/basic") {
call.respondText(
"Hello, ${call.principal<UserIdPrincipal>()?.name}!"
)
}
}
curl -i http://localhost:8000/basic
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Access to the '/basic' path",
charset=UTF-8
Content-Length: 0
curl -i -H "Authorization: Basic dHV0b3I6dHV0b3I="
http://localhost:8000/basic
HTTP/1.1 200 OK
Content-Length: 13
Content-Type: text/plain; charset=UTF-8
fun getMd5Digest(str: String): ByteArray =
MessageDigest.getInstance("MD5").digest(str.toByteArray())
const val digestRealm = "Access to the '/digest' path"
val usersHash: Map<String, ByteArray> = userList.associate {
it.username to
getMd5Digest("${it.username}:$digestRealm:${it.password}")
}
digest("auth-digest") {
realm = digestRealm
digestProvider { userName, realm ->
usersHash[userName]
}
}
routing {
authenticate("auth-digest") {
get("/digest") {
call.respondText(
"Hello, ${call.principal<UserIdPrincipal>()?.name}!")
}
}
curl -i http://localhost:8000/digest
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="Access to the '/digest' path",
nonce="fb1bffee9d86d7d4", algorithm="MD5"
Content-Length: 0
curl -i -H @digest-header.txt http://localhost:8000/digest
HTTP/1.1 200 OK
Content-Length: 13
Content-Type: text/plain; charset=UTF-8
data class UserSession(
val name: String, val count: Int
) : Principal
form("auth-form") {
userParamName = "username"
passwordParamName = "password"
validate(validator()) }
session<UserSession>("auth-session") {
validate { session ->
session }
challenge {
call.respondRedirect("/form-login") } }
authenticate("auth-form") {
post("/form-login") {
val userName = call.principal<UserIdPrincipal>()
?.name.toString()
call.sessions.set(UserSession(userName, 1))
call.respondText("Hello, $userName!") } }
authenticate("auth-session") {
get("/session") {
val userSession = call.principal<UserSession>()
call.sessions.set(userSession
?.copy(count = userSession.count + 1))
call.respondText("Hello, ${userSession?.name}") } }
curl -i
-H "Content-Type: application/x-www-form-urlencoded"
-d "username=tutor&password=tutor"
-X POST http://localhost:8000/form-login
HTTP/1.1 200 OK
user_session: count=%23i1&name=%23stutor
Content-Length: 13
Content-Type: text/plain; charset=UTF-8
curl -v -H "user_session: count=%23i1&name=%23stutor"
http://localhost:8000/session
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /session HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.55.1
> Accept: */*
> user_session: count=%23i1&name=%23stutor
< HTTP/1.1 200 OK
< user_session: count=%23i2&name=%23stutor
< Content-Length: 12
< Content-Type: text/plain; charset=UTF-8
Hello, tutor* Connection #0 to host localhost left intact
jwt("auth-jwt") {
realm = jwtRealm
verifier(JWT
.require(Algorithm.HMAC256(secret))
.withAudience(audience)
.withIssuer(issuer)
.build() )
validate { credential ->
if (credential.payload.getClaim("username").asString()
!= "") {
JWTPrincipal(credential.payload)
} else {
null } } }
post("jwt-login") {
val user = call.receive<User>()
val token = JWT.create()
.withAudience(audience)
.withIssuer(issuer)
.withClaim("username", user.username)
.withExpiresAt(
Date(System.currentTimeMillis() + 600000))
.sign(Algorithm.HMAC256(secret))
call.respond(hashMapOf("token" to token))
}
post("jwt-login") {
authenticate("auth-jwt") {
get("/jwt") {
val principal = call.principal<JWTPrincipal>()
val username = principal!!.payload
.getClaim("username").asString()
val expiresAt = principal.expiresAt
?.time?.minus(System.currentTimeMillis())
call.respondText(
"Hello, $username! Token is expired at $expiresAt ms.")
}
}
Auth — открытый протокол (схема) авторизации, обеспечивающий предоставление третьей стороне ограниченный доступ к защищённым ресурсам пользователя без передачи ей (третьей стороне) логина и пароля