diff --git a/build.gradle.kts b/build.gradle.kts index 40fc23e..f2b1945 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -35,9 +35,8 @@ dependencies { implementation("org.jetbrains.exposed:exposed-dao:$exposed_version") implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1") implementation ("org.jetbrains.exposed:exposed-java-time:$exposed_version") - implementation("io.jsonwebtoken:jjwt-api:0.11.5") - implementation("io.jsonwebtoken:jjwt-impl:0.11.5") - implementation("io.jsonwebtoken:jjwt-jackson:0.11.5") + implementation("io.ktor:ktor-server-auth:$ktor_version") + implementation("io.ktor:ktor-server-auth-jwt:$ktor_version") testImplementation("io.ktor:ktor-server-test-host-jvm") testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version") } diff --git a/src/main/kotlin/eu/maiora/Application.kt b/src/main/kotlin/eu/maiora/Application.kt index a0c43f3..bfd7600 100644 --- a/src/main/kotlin/eu/maiora/Application.kt +++ b/src/main/kotlin/eu/maiora/Application.kt @@ -1,7 +1,6 @@ package eu.maiora import eu.maiora.plugins.configureDatabases -//import eu.maiora.model.LogScriptRepositoryImpl import eu.maiora.plugins.* import io.ktor.http.* import io.ktor.server.application.* @@ -21,11 +20,10 @@ fun Application.module() { val dbUrl = config.property("ktor.database.url").getString(); val username = config.property("ktor.database.username").getString(); val password = config.property("ktor.database.password").getString(); - //val repository = LogScriptRepositoryImpl() configureDatabases(dbUrl, username, password) - //configureRouting(dbUrl, username, password, repository) configureRouting(dbUrl, username, password) configureSerialization() + install(CallLogging) install(CORS){ anyHost() diff --git a/src/main/kotlin/eu/maiora/plugins/Routing.kt b/src/main/kotlin/eu/maiora/plugins/Routing.kt index 40887ee..abfd7e4 100644 --- a/src/main/kotlin/eu/maiora/plugins/Routing.kt +++ b/src/main/kotlin/eu/maiora/plugins/Routing.kt @@ -18,9 +18,6 @@ fun Application.configureRouting(dbUrl : String, username : String, password : S call.respondText("Hello World!") } - auth(AccountsRepositoryImpl(), ParametriRepositoryImpl()) - //analizzaURLRoute() - //eseguiScriptSQLRoute(dbUrl, username, password) - //logScriptRouting(repository) + auth(AccountsRepositoryImpl()) } } diff --git a/src/main/kotlin/eu/maiora/routes/Auth.kt b/src/main/kotlin/eu/maiora/routes/Auth.kt index 7b3274c..c6a2cbb 100644 --- a/src/main/kotlin/eu/maiora/routes/Auth.kt +++ b/src/main/kotlin/eu/maiora/routes/Auth.kt @@ -1,13 +1,11 @@ package eu.maiora.routes -import com.fasterxml.jackson.databind.ser.Serializers.Base +import com.auth0.jwt.JWT +import com.auth0.jwt.algorithms.Algorithm import eu.maiora.model.AccountsRepositoryImpl -import eu.maiora.model.ParametriRepositoryImpl -import io.jsonwebtoken.Jwts -import io.jsonwebtoken.SignatureAlgorithm -import io.jsonwebtoken.security.Keys import io.ktor.http.* import io.ktor.server.application.* +import io.ktor.server.config.* import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* @@ -17,70 +15,77 @@ import org.slf4j.LoggerFactory import java.util.* -fun Route.auth(accountsRepository: AccountsRepositoryImpl, parametriRepository: ParametriRepositoryImpl){ - - post("/auth"){ - // Riceve il body della richiesta e lo deserializza in ReceivedResponse - val receivedResponse = try { - call.receive() - } catch (e: Exception) { - return@post call.respondText("Body mancante " + e.stackTraceToString(), status = HttpStatusCode.BadRequest) - } - val logger = LoggerFactory.getLogger("AuthRoute") - logger.info("param: " + - receivedResponse.param); - - // Decodifica la stringa da Base64 a oggetto Credentials - val decodedBytes = Base64.getDecoder().decode(receivedResponse.param) - val decodedString = String(decodedBytes) - val credentials = Json.decodeFromString(decodedString) - - - - - //verifica credenziali (recupero account dal database) - val account = accountsRepository.accountByUsername(credentials.username) - //se le credenziali sono valide, creare il JWT - if (account != null) { - val passwordPlain = String( - Base64.getDecoder().decode( - StringBuffer( - String( - Base64.getDecoder().decode(account.password.toByteArray()) - ) - ).reverse().toString().toByteArray() +fun Route.auth(accountsRepository: AccountsRepositoryImpl) { + route("/auth") { + post() { + // Riceve il body della richiesta e lo deserializza in ReceivedResponse + val receivedResponse = try { + call.receive() + } catch (e: Exception) { + return@post call.respondText( + "Body mancante " + e.stackTraceToString(), + status = HttpStatusCode.BadRequest ) - ) - if(passwordPlain.equals(credentials.password)){ - val parametro = parametriRepository.parametroByChiave("jwt_secret") - if (parametro != null) { + } + val logger = LoggerFactory.getLogger("AuthRoute") + logger.info( + "param: " + + receivedResponse.param + ); + + // Decodifica la stringa da Base64 a oggetto Credentials + val decodedBytes = Base64.getDecoder().decode(receivedResponse.param) + val decodedString = String(decodedBytes) + val credentials = try { + Json.decodeFromString(decodedString) + } catch (e: Exception) { + return@post call.respondText( + "Errore nel param. Verificare la codifica. \n" + e.stackTraceToString(), + status = HttpStatusCode.BadRequest + ) + } + + //verifica credenziali (recupero account dal database) + val account = accountsRepository.accountByUsername(credentials.username) + //se le credenziali sono valide, creare il JWT + if (account != null) { + val passwordPlain = String( + Base64.getDecoder().decode( + StringBuffer( + String( + Base64.getDecoder().decode(account.password.toByteArray()) + ) + ).reverse().toString().toByteArray() + ) + ) + if (passwordPlain.equals(credentials.password)) { + val config = ApplicationConfig("application.conf") + val secret = config.property("ktor.jwt.secret").getString() - val key = Keys.hmacShaKeyFor(parametro.valore.toByteArray()) val now = System.currentTimeMillis() val expiration = now + 86400000 // Scadenza tra 1 giorno (24 ore) - val token = Jwts.builder() - .setSubject(account.username) // Soggetto del JWT - .setIssuedAt(Date(now)) // Data di emissione - .setExpiration(Date(expiration)) // Data di scadenza - .signWith(key, SignatureAlgorithm.HS256) // Firma con una chiave segreta - .compact() + val token = JWT.create() + .withSubject(account.username) + .withIssuedAt(Date(now)) + .withExpiresAt(Date(expiration)) + .sign(Algorithm.HMAC256(secret)) // Risponde con la stringa decodificata call.respond(HttpStatusCode.OK, token) - } - } - else { + } else { + call.respond(HttpStatusCode.Unauthorized) + } + } else { call.respond(HttpStatusCode.Unauthorized) } - } - else { - call.respond(HttpStatusCode.Unauthorized) - } + } } + + } @Serializable diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 0aecf29..2037c99 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -13,4 +13,9 @@ ktor { ;username = "EP_DONORIONE" ;password = "ep_donorione" } -} \ No newline at end of file + jwt { + # secret per JWT generato partendo dalla stringa '?Backend_API*06022025!' codificato in Base64 + secret = "P0JhY2tlbmRfQVBJKjA2MDIyMDI1IQ==" + } +} +