Authentication and authorization plugin for Ktor server applications
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Comprehensive authentication and authorization capabilities for Ktor server applications. This module provides support for multiple authentication mechanisms including Basic, Bearer, Form-based, Session-based, Digest, OAuth 1.0a, and OAuth 2.0 authentication through a flexible provider-based architecture.
implementation("io.ktor:ktor-server-auth-jvm:3.2.0")import io.ktor.server.auth.*
import io.ktor.server.application.*
import io.ktor.server.routing.*import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.routing.*
import io.ktor.server.response.*
fun Application.configureAuthentication() {
install(Authentication) {
basic("auth-basic") {
realm = "Access to the '/' path"
validate { credentials ->
if (credentials.name == "admin" && credentials.password == "password") {
UserIdPrincipal(credentials.name)
} else null
}
}
}
routing {
authenticate("auth-basic") {
get("/protected") {
val principal = call.principal<UserIdPrincipal>()
call.respond("Hello ${principal?.name}!")
}
}
}
}The Ktor authentication module follows a provider-based architecture:
Main plugin for handling authentication and authorization.
object Authentication : BaseApplicationPlugin<Application, AuthenticationConfig, Authentication>
fun Application.authentication(block: AuthenticationConfig.() -> Unit)
class AuthenticationConfig {
fun provider(name: String?, configure: DynamicProviderConfig.() -> Unit)
fun register(provider: AuthenticationProvider)
}
class DynamicProviderConfig(name: String?) {
fun authenticate(block: (context: AuthenticationContext) -> Unit)
}val ApplicationCall.authentication: AuthenticationContext
inline fun <reified P : Any> ApplicationCall.principal(): P?
inline fun <reified P : Any> ApplicationCall.principal(provider: String?): P?
class AuthenticationContext {
fun principal(principal: Any)
fun principal(provider: String?, principal: Any)
fun <T> principal(provider: String? = null): T?
fun challenge(key: Any, cause: AuthenticationFailedCause, function: ChallengeFunction)
fun error(key: Any, cause: AuthenticationFailedCause)
val allErrors: List<AuthenticationFailedCause>
val allFailures: List<AuthenticationFailedCause>
}fun Route.authenticate(
vararg configurations: String? = arrayOf(null),
optional: Boolean = false,
build: Route.() -> Unit
): Route
fun Route.authenticate(
vararg configurations: String? = arrayOf(null),
strategy: AuthenticationStrategy,
build: Route.() -> Unit
): Route
enum class AuthenticationStrategy {
Optional, FirstSuccessful, Required
}
class AuthenticationRouteSelector(val names: List<String?>)
object AuthenticationCheckedHTTP Basic authentication with username and password validation.
fun AuthenticationConfig.basic(
name: String? = null,
configure: BasicAuthenticationProvider.Config.() -> Unit
)Bearer token authentication for API access tokens and JWT tokens.
fun AuthenticationConfig.bearer(
name: String? = null,
configure: BearerAuthenticationProvider.Config.() -> Unit
)Form-based and session-based authentication for web applications.
fun AuthenticationConfig.form(
name: String? = null,
configure: FormAuthenticationProvider.Config.() -> Unit
)
fun <T : Any> AuthenticationConfig.session(
name: String? = null,
configure: SessionAuthenticationProvider.Config<T>.() -> Unit
)Form and Session Authentication
OAuth 1.0a and OAuth 2.0 support for third-party authentication providers.
fun AuthenticationConfig.oauth(
name: String? = null,
configure: OAuthAuthenticationProvider.Config.() -> Unit
)Digest authentication and comprehensive OAuth 1.0a support available only on JVM platform.
fun AuthenticationConfig.digest(
name: String? = null,
configure: DigestAuthenticationProvider.Config.() -> Unit
)data class UserPasswordCredential(val name: String, val password: String)
data class BearerTokenCredential(val token: String)data class UserIdPrincipal(val name: String)class UserHashedTableAuth(
table: Map<String, ByteArray>,
digester: (String) -> String
) {
fun authenticate(credential: UserPasswordCredential): UserIdPrincipal?
}fun ApplicationRequest.parseAuthorizationHeader(): HttpAuthHeader?sealed class AuthenticationFailedCause {
data object NoCredentials : AuthenticationFailedCause()
data object InvalidCredentials : AuthenticationFailedCause()
open class Error(val message: String) : AuthenticationFailedCause()
}
typealias ChallengeFunction = suspend PipelineContext<*, ApplicationCall>.(String, String) -> Unit
typealias AuthenticationFunction<C> = suspend ApplicationCall.(C) -> Any?
typealias ApplicationCallPredicate = (ApplicationCall) -> Booleanclass UnauthorizedResponse(
challenge: HttpAuthHeader = HttpAuthHeader.basicAuthChallenge("Ktor Server")
) : HttpStatusCodeContent
class ForbiddenResponse(message: String = "Forbidden") : HttpStatusCodeContent