mirror of https://github.com/usbharu/Hideout.git
feat: 自動で鍵を作成するように
This commit is contained in:
parent
f0383e3a95
commit
aebf0862e0
|
@ -0,0 +1,5 @@
|
|||
package dev.usbharu.hideout.domain.model.hideout.entity
|
||||
|
||||
import java.util.*
|
||||
|
||||
data class Jwt(val kid: UUID, val privateKey: String, val publicKey: String)
|
|
@ -7,7 +7,10 @@ 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.repository.IMetaRepository
|
||||
import dev.usbharu.hideout.service.IUserAuthService
|
||||
import dev.usbharu.hideout.util.JsonWebKeyUtil
|
||||
import dev.usbharu.hideout.util.RsaUtil
|
||||
import io.ktor.http.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.auth.*
|
||||
|
@ -15,19 +18,27 @@ import io.ktor.server.auth.jwt.*
|
|||
import io.ktor.server.request.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import kotlinx.coroutines.runBlocking
|
||||
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 = "jwt-auth"
|
||||
|
||||
fun Application.configureSecurity(userAuthService: IUserAuthService) {
|
||||
fun Application.configureSecurity(userAuthService: IUserAuthService, metaRepository: IMetaRepository) {
|
||||
|
||||
val privateKeyString = property("jwt.privateKey")
|
||||
val issuer = property("jwt.issuer")
|
||||
val privateKeyString = runBlocking {
|
||||
requireNotNull(metaRepository.get()).jwt.privateKey
|
||||
}
|
||||
val publicKey = runBlocking {
|
||||
val publicKey = requireNotNull(metaRepository.get()).jwt.publicKey
|
||||
println(publicKey)
|
||||
RsaUtil.decodeRsaPublicKey(Base64.getDecoder().decode(publicKey))
|
||||
}
|
||||
println(privateKeyString)
|
||||
val issuer = property("hideout.url")
|
||||
// val audience = property("jwt.audience")
|
||||
val myRealm = property("jwt.realm")
|
||||
val jwkProvider = JwkProviderBuilder(issuer)
|
||||
|
@ -57,8 +68,6 @@ fun Application.configureSecurity(userAuthService: IUserAuthService) {
|
|||
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()
|
||||
|
@ -66,22 +75,16 @@ fun Application.configureSecurity(userAuthService: IUserAuthService) {
|
|||
// .withIssuer(issuer)
|
||||
.withClaim("username", user.username)
|
||||
.withExpiresAt(Date(System.currentTimeMillis() + 60000))
|
||||
.sign(Algorithm.RSA256(publicKey as RSAPublicKey, privateKey as RSAPrivateKey))
|
||||
.sign(Algorithm.RSA256(publicKey, privateKey as RSAPrivateKey))
|
||||
return@post call.respond(hashSetOf("token" to token))
|
||||
}
|
||||
|
||||
get("/.well-known/jwks.json"){
|
||||
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"
|
||||
}
|
||||
]
|
||||
}""")
|
||||
call.respondText(
|
||||
contentType = ContentType.Application.Json,
|
||||
text = JsonWebKeyUtil.publicKeyToJwk(requireNotNull(metaRepository.get()).jwt.publicKey)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,8 +43,8 @@ class ServerInitialiseServiceImpl(private val metaRepository: IMetaRepository) :
|
|||
val generateKeyPair = keyPairGenerator.generateKeyPair()
|
||||
val jwt = Jwt(
|
||||
UUID.randomUUID(),
|
||||
Base64.getEncoder().encodeToString(generateKeyPair.public.encoded),
|
||||
Base64.getEncoder().encodeToString(generateKeyPair.private.encoded)
|
||||
Base64.getEncoder().encodeToString(generateKeyPair.private.encoded),
|
||||
Base64.getEncoder().encodeToString(generateKeyPair.public.encoded)
|
||||
)
|
||||
val meta = Meta(implementationVersion, jwt)
|
||||
metaRepository.save(meta)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package dev.usbharu.hideout.util
|
||||
|
||||
import java.math.BigInteger
|
||||
import java.security.KeyFactory
|
||||
import java.security.interfaces.RSAPublicKey
|
||||
import java.security.spec.X509EncodedKeySpec
|
||||
import java.util.*
|
||||
|
||||
object JsonWebKeyUtil {
|
||||
|
||||
fun publicKeyToJwk(publicKey: String): String {
|
||||
val x509EncodedKeySpec = X509EncodedKeySpec(Base64.getDecoder().decode(publicKey))
|
||||
val generatePublic = KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec)
|
||||
return publicKeyToJwk(generatePublic as RSAPublicKey)
|
||||
}
|
||||
|
||||
fun publicKeyToJwk(publicKey: RSAPublicKey): String {
|
||||
val e = encodeBase64UInt(publicKey.publicExponent)
|
||||
val n = encodeBase64UInt(publicKey.modulus)
|
||||
return """{"e":"$e","n":"$n","use":"sig","kty":"RSA"}"""
|
||||
}
|
||||
|
||||
private fun encodeBase64UInt(bigInteger: BigInteger, minLength: Int = -1): String {
|
||||
if(bigInteger.signum() < 0){
|
||||
throw IllegalArgumentException("Cannot encode negative numbers")
|
||||
}
|
||||
|
||||
var bytes = bigInteger.toByteArray()
|
||||
if (bigInteger.bitLength() % 8 == 0 && (bytes[0] == 0.toByte()) && bytes.size > 1){
|
||||
bytes = Arrays.copyOfRange(bytes, 1, bytes.size)
|
||||
}
|
||||
if (minLength != -1){
|
||||
if (bytes.size < minLength){
|
||||
val array = ByteArray(minLength)
|
||||
System.arraycopy(bytes, 0, array, minLength - bytes.size, bytes.size)
|
||||
bytes = array
|
||||
}
|
||||
}
|
||||
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package dev.usbharu.hideout.util
|
||||
|
||||
import java.security.KeyFactory
|
||||
import java.security.interfaces.RSAPrivateKey
|
||||
import java.security.interfaces.RSAPublicKey
|
||||
import java.security.spec.PKCS8EncodedKeySpec
|
||||
import java.security.spec.X509EncodedKeySpec
|
||||
|
||||
object RsaUtil {
|
||||
fun decodeRsaPublicKey(byteArray: ByteArray):RSAPublicKey{
|
||||
val x509EncodedKeySpec = X509EncodedKeySpec(byteArray)
|
||||
return KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec) as RSAPublicKey
|
||||
}
|
||||
|
||||
fun decodeRsaPrivateKey(byteArray: ByteArray):RSAPrivateKey{
|
||||
val pkcS8EncodedKeySpec = PKCS8EncodedKeySpec(byteArray)
|
||||
return KeyFactory.getInstance("RSA").generatePrivate(pkcS8EncodedKeySpec) as RSAPrivateKey
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue