Kotlin 中的授权与认证:工具概览与实践示例
在现代 Kotlin Web 开发中,应用程序的安全性始于正确实现认证(验证用户身份)和授权(验证访问权限)。本文将详细讲解在 Kotlin 中创建安全应用程序的主要库和方法——既包括服务器端(Ktor、Spring Boot),也包括移动 Android 应用程序。
1. 基本概念:认证 vs 授权
认证(Authentication)——是验证用户身份的过程(登录名+密码、令牌、生物识别)。
授权(Authorization)——是确定经过认证的用户可以访问哪些资源和操作(角色、权限)。
在 Kotlin 中,这两个任务都可以通过专门的库来解决,我们将在下面介绍这些库。
2. Ktor 中的认证(服务器框架)
Ktor 是 JetBrains 开发的现代异步服务器。它提供了内置的 ktor-server-auth 模块用于认证。
添加依赖(Gradle)
implementation("io.ktor:ktor-server-auth:$ktor_version")implementation("io.ktor:ktor-server-auth-jwt:$ktor_version") // 用于 JWT示例:基于 JWT 令牌的认证
import io.ktor.server.auth.*import io.ktor.server.auth.jwt.*import com.auth0.jwk.JwkProviderimport io.ktor.server.application.*
fun Application.configureAuth() { install(Authentication) { jwt("auth-jwt") { val jwkProvider = JwkProvider("https://your-auth-domain/.well-known/jwks.json") verifier(jwkProvider) validate { credential -> if (credential.payload.audience.contains("my-app")) { JWTPrincipal(credential.payload) } else null } } }}
// 在路由中:authenticate("auth-jwt") { get("/protected") { val principal = call.principal<JWTPrincipal>() call.respondText("访问已授权给用户:${principal?.payload?.subject}") }}3. 用于 Kotlin 的 Spring Security
Spring Security 是保护 Spring Boot 应用程序的事实标准。在 Kotlin 中,它使用 DSL 配置。
添加到项目(Gradle)
implementation("org.springframework.boot:spring-boot-starter-security")implementation("org.springframework.boot:spring-boot-starter-web")Kotlin 中的 SecurityConfig 配置
import org.springframework.context.annotation.Beanimport org.springframework.context.annotation.Configurationimport org.springframework.security.config.annotation.web.builders.HttpSecurityimport org.springframework.security.config.annotation.web.configuration.EnableWebSecurityimport org.springframework.security.core.userdetails.Userimport org.springframework.security.provisioning.InMemoryUserDetailsManagerimport org.springframework.security.web.SecurityFilterChain
@Configuration@EnableWebSecurityclass SecurityConfig {
@Bean fun filterChain(http: HttpSecurity): SecurityFilterChain { http .authorizeHttpRequests { auth -> auth.requestMatchers("/admin/**").hasRole("ADMIN") .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN") .anyRequest().authenticated() } .httpBasic() return http.build() }
@Bean fun users(): InMemoryUserDetailsManager { val user = User.withDefaultPasswordEncoder() .username("user").password("pass").roles("USER").build() val admin = User.withDefaultPasswordEncoder() .username("admin").password("admin").roles("ADMIN").build() return InMemoryUserDetailsManager(user, adm