Ktor 서버의 기본 인증
필수 의존성: io.ktor:ktor-server-auth
코드 예시: auth-basic, auth-basic-hash-table
기본 인증 스키마는 접근 제어 및 인증에 사용되는 HTTP 프레임워크의 일부입니다. 이 스키마에서는 사용자 자격 증명(credentials)이 Base64로 인코딩된 사용자 이름/비밀번호 쌍으로 전송됩니다.
Ktor를 사용하면 사용자 로그인 및 특정 경로 보호를 위해 기본 인증을 사용할 수 있습니다. Ktor의 인증에 대한 일반적인 정보는 Ktor 서버의 인증 및 권한 부여 섹션에서 얻을 수 있습니다.
기본 인증은 사용자 이름과 비밀번호를 평문(clear text)으로 전송하므로 민감한 정보를 보호하기 위해 HTTPS/TLS를 사용해야 합니다.
의존성 추가
basic
인증을 활성화하려면 빌드 스크립트에 ktor-server-auth
아티팩트를 포함해야 합니다:
기본 인증 흐름
기본 인증 흐름은 다음과 같습니다:
- 클라이언트가 서버 애플리케이션의 특정 경로로
Authorization
헤더 없이 요청을 보냅니다. - 서버는 클라이언트에게
401
(Unauthorized) 응답 상태로 응답하고,WWW-Authenticate
응답 헤더를 사용하여 해당 경로를 보호하는 데 기본 인증 스키마가 사용되었음을 알립니다. 일반적인WWW-Authenticate
헤더는 다음과 같습니다:
WWW-Authenticate: Basic realm="Access to the '/' path", charset="UTF-8"
Ktor에서는 basic
인증 공급자(provider)를 구성할 때 해당 속성을 사용하여 realm과 charset을 지정할 수 있습니다.
- 일반적으로 클라이언트는 사용자가 자격 증명을 입력할 수 있는 로그인 대화 상자를 표시합니다. 그런 다음 클라이언트는 Base64로 인코딩된 사용자 이름과 비밀번호 쌍을 포함하는
Authorization
헤더를 사용하여 요청을 보냅니다. 예를 들면 다음과 같습니다:
Authorization: Basic amV0YnJhaW5zOmZvb2Jhcg
- 서버는 클라이언트가 보낸 자격 증명을 검증하고 요청된 콘텐츠로 응답합니다.
기본 인증 설치
basic
인증 공급자(provider)를 설치하려면 install
블록 내에서 basic 함수를 호출합니다:
import io.ktor.server.application.*
import io.ktor.server.auth.*
// ...
install(Authentication) {
basic {
// Configure basic authentication
}
}
선택적으로 지정된 경로를 인증하는 데 사용할 수 있는 공급자 이름을 지정할 수 있습니다.
기본 인증 구성
Ktor에서 다양한 인증 공급자(provider)를 구성하는 방법에 대한 일반적인 아이디어를 얻으려면 인증 구성을 참조하세요. 이 섹션에서는 basic
인증 공급자의 특정 구성에 대해 살펴보겠습니다.
1단계: 기본 공급자 구성
basic
인증 공급자(provider)는 BasicAuthenticationProvider.Configuration 클래스를 통해 설정을 노출합니다. 아래 예시에서는 다음 설정이 지정되어 있습니다:
realm
속성은WWW-Authenticate
헤더에 전달될 realm을 설정합니다.validate
함수는 사용자 이름과 비밀번호를 검증합니다.
install(Authentication) {
basic("auth-basic") {
realm = "Access to the '/' path"
validate { credentials ->
if (credentials.name == "jetbrains" && credentials.password == "foobar") {
UserIdPrincipal(credentials.name)
} else {
null
}
}
}
}
validate
함수는 UserPasswordCredential
을 확인하고 인증에 성공하면 UserIdPrincipal
을 반환하며, 인증에 실패하면 null
을 반환합니다.
사용자 이름과 비밀번호 해시를 보관하는 인메모리 테이블에 저장된 사용자를 검증하기 위해 UserHashedTableAuth를 사용할 수도 있습니다.
2단계: 특정 리소스 보호
basic
공급자(provider)를 구성한 후, authenticate 함수를 사용하여 애플리케이션의 특정 리소스를 보호할 수 있습니다. 인증에 성공한 경우, 라우트 핸들러 내에서 call.principal
함수를 사용하여 인증된 UserIdPrincipal을 검색하고 인증된 사용자의 이름을 얻을 수 있습니다.
routing {
authenticate("auth-basic") {
get("/") {
call.respondText("Hello, ${call.principal<UserIdPrincipal>()?.name}!")
}
}
}
UserHashedTableAuth로 검증하기
Ktor를 사용하면 사용자 이름과 비밀번호 해시를 보관하는 인메모리 테이블에 저장된 사용자를 검증하기 위해 UserHashedTableAuth를 사용할 수 있습니다. 이를 통해 데이터 소스가 유출되더라도 사용자 비밀번호가 손상되지 않도록 할 수 있습니다.
UserHashedTableAuth
를 사용하여 사용자를 검증하려면 다음 단계를 따르세요:
- getDigestFunction 함수를 사용하여 지정된 알고리즘과 솔트 공급자(salt provider)로 다이제스트 함수를 생성합니다:
val digestFunction = getDigestFunction("SHA-256") { "ktor${it.length}" }
UserHashedTableAuth
의 새 인스턴스를 초기화하고 다음 속성을 지정합니다:
table
속성을 사용하여 사용자 이름과 해시된 비밀번호 테이블을 제공합니다.digester
속성에 다이제스트 함수를 할당합니다.
val hashedUserTable = UserHashedTableAuth(
table = mapOf(
"jetbrains" to digestFunction("foobar"),
"admin" to digestFunction("password")
),
digester = digestFunction
)
validate
함수 내부에서 UserHashedTableAuth.authenticate 함수를 호출하여 사용자를 인증하고, 자격 증명이 유효하면UserIdPrincipal
인스턴스를 반환합니다:
install(Authentication) {
basic("auth-basic-hashed") {
realm = "Access to the '/' path"
validate { credentials ->
hashedUserTable.authenticate(credentials)
}
}
}