mirror of https://github.com/usbharu/Hideout.git
feat: サンプルの値を使ってJWTでログイントークンを発行できるように
This commit is contained in:
parent
8a3b83f644
commit
83b99e305d
|
@ -97,6 +97,7 @@ fun Application.parent() {
|
||||||
configureMonitoring()
|
configureMonitoring()
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
register(inject<IUserService>().value)
|
register(inject<IUserService>().value)
|
||||||
|
configureSecurity(inject<IUserAuthService>().value)
|
||||||
configureRouting(
|
configureRouting(
|
||||||
inject<HttpSignatureVerifyService>().value,
|
inject<HttpSignatureVerifyService>().value,
|
||||||
inject<ActivityPubService>().value,
|
inject<ActivityPubService>().value,
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.hideout.form
|
||||||
|
|
||||||
|
data class UserLogin(val username: String, val password: String)
|
|
@ -2,24 +2,86 @@
|
||||||
|
|
||||||
package dev.usbharu.hideout.plugins
|
package dev.usbharu.hideout.plugins
|
||||||
|
|
||||||
|
import com.auth0.jwk.JwkProviderBuilder
|
||||||
|
import com.auth0.jwt.JWT
|
||||||
|
import com.auth0.jwt.algorithms.Algorithm
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.form.UserLogin
|
||||||
|
import dev.usbharu.hideout.property
|
||||||
import dev.usbharu.hideout.service.IUserAuthService
|
import dev.usbharu.hideout.service.IUserAuthService
|
||||||
|
import io.ktor.http.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import io.ktor.server.auth.*
|
import io.ktor.server.auth.*
|
||||||
|
import io.ktor.server.auth.jwt.*
|
||||||
|
import io.ktor.server.request.*
|
||||||
|
import io.ktor.server.response.*
|
||||||
|
import io.ktor.server.routing.*
|
||||||
|
import java.security.KeyFactory
|
||||||
|
import java.security.interfaces.RSAPrivateKey
|
||||||
|
import java.security.interfaces.RSAPublicKey
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
const val TOKEN_AUTH = "token-auth"
|
const val TOKEN_AUTH = "jwt-auth"
|
||||||
|
|
||||||
fun Application.configureSecurity(userAuthService: IUserAuthService) {
|
fun Application.configureSecurity(userAuthService: IUserAuthService) {
|
||||||
|
|
||||||
|
val privateKeyString = property("jwt.privateKey")
|
||||||
|
val issuer = property("jwt.issuer")
|
||||||
|
// val audience = property("jwt.audience")
|
||||||
|
val myRealm = property("jwt.realm")
|
||||||
|
val jwkProvider = JwkProviderBuilder(issuer)
|
||||||
|
.cached(10, 24, TimeUnit.HOURS)
|
||||||
|
.rateLimited(10, 1, TimeUnit.MINUTES)
|
||||||
|
.build()
|
||||||
install(Authentication) {
|
install(Authentication) {
|
||||||
bearer(TOKEN_AUTH) {
|
jwt(TOKEN_AUTH) {
|
||||||
authenticate { bearerTokenCredential ->
|
realm = myRealm
|
||||||
UserIdPrincipal(bearerTokenCredential.token)
|
verifier(jwkProvider, issuer) {
|
||||||
|
acceptLeeway(3)
|
||||||
|
}
|
||||||
|
validate { jwtCredential ->
|
||||||
|
if (jwtCredential.payload.getClaim("username").asString().isNotEmpty()) {
|
||||||
|
JWTPrincipal(jwtCredential.payload)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
skipWhen { true }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// install(Sessions) {
|
|
||||||
// cookie<UserSession>("MY_SESSION") {
|
routing {
|
||||||
// cookie.extensions["SameSite"] = "lax"
|
post("/login") {
|
||||||
// }
|
val user = call.receive<UserLogin>()
|
||||||
// }
|
val check = userAuthService.verifyAccount(user.username, user.password)
|
||||||
|
if (check.not()) {
|
||||||
|
return@post call.respond(HttpStatusCode.Unauthorized)
|
||||||
|
}
|
||||||
|
|
||||||
|
val publicKey = jwkProvider.get("6f8856ed-9189-488f-9011-0ff4b6c08edc").publicKey
|
||||||
|
val keySpecPKCS8 = PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyString))
|
||||||
|
val privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpecPKCS8)
|
||||||
|
val token = JWT.create()
|
||||||
|
// .withAudience(audience)
|
||||||
|
// .withIssuer(issuer)
|
||||||
|
.withClaim("username", user.username)
|
||||||
|
.withExpiresAt(Date(System.currentTimeMillis() + 60000))
|
||||||
|
.sign(Algorithm.RSA256(publicKey as RSAPublicKey, privateKey as RSAPrivateKey))
|
||||||
|
return@post call.respond(hashSetOf("token" to token))
|
||||||
|
}
|
||||||
|
|
||||||
|
get("/.well-known/jwks.json"){
|
||||||
|
//language=JSON
|
||||||
|
call.respondText(contentType = ContentType.Application.Json,text = """{
|
||||||
|
"keys": [
|
||||||
|
{
|
||||||
|
"kty": "RSA",
|
||||||
|
"e": "AQAB",
|
||||||
|
"kid": "6f8856ed-9189-488f-9011-0ff4b6c08edc",
|
||||||
|
"n":"tfJaLrzXILUg1U3N1KV8yJr92GHn5OtYZR7qWk1Mc4cy4JGjklYup7weMjBD9f3bBVoIsiUVX6xNcYIr0Ie0AQ"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}""")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package dev.usbharu.hideout.routing
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.service.IUserAuthService
|
||||||
|
import io.ktor.server.routing.*
|
||||||
|
|
||||||
|
fun Routing.login(userAuthService: IUserAuthService){
|
||||||
|
|
||||||
|
}
|
|
@ -20,3 +20,10 @@ hideout {
|
||||||
password = ""
|
password = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jwt {
|
||||||
|
privateKey = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAtfJaLrzXILUg1U3N1KV8yJr92GHn5OtYZR7qWk1Mc4cy4JGjklYup7weMjBD9f3bBVoIsiUVX6xNcYIr0Ie0AQIDAQABAkEAg+FBquToDeYcAWBe1EaLVyC45HG60zwfG1S4S3IB+y4INz1FHuZppDjBh09jptQNd+kSMlG1LkAc/3znKTPJ7QIhANpyB0OfTK44lpH4ScJmCxjZV52mIrQcmnS3QzkxWQCDAiEA1Tn7qyoh+0rOO/9vJHP8U/beo51SiQMw0880a1UaiisCIQDNwY46EbhGeiLJR1cidr+JHl86rRwPDsolmeEF5AdzRQIgK3KXL3d0WSoS//K6iOkBX3KMRzaFXNnDl0U/XyeGMuUCIHaXv+n+Brz5BDnRbWS+2vkgIe9bUNlkiArpjWvX+2we"
|
||||||
|
issuer = "http://0.0.0.0:8080/"
|
||||||
|
audience = "http://0.0.0.0:8080/hello"
|
||||||
|
realm = "Access to 'hello'"
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue