add tamper protection
This commit is contained in:
parent
10813529f2
commit
b4a6308d5a
@ -15,6 +15,7 @@ import com.restapi.domain.Session
|
|||||||
import com.restapi.domain.Session.objectMapper
|
import com.restapi.domain.Session.objectMapper
|
||||||
import com.restapi.domain.Session.redis
|
import com.restapi.domain.Session.redis
|
||||||
import com.restapi.domain.Session.setAuthorizedUser
|
import com.restapi.domain.Session.setAuthorizedUser
|
||||||
|
import com.restapi.domain.Session.signPayload
|
||||||
import io.ebean.DataIntegrityException
|
import io.ebean.DataIntegrityException
|
||||||
import io.ebean.DuplicateKeyException
|
import io.ebean.DuplicateKeyException
|
||||||
import io.javalin.Javalin
|
import io.javalin.Javalin
|
||||||
@ -32,9 +33,12 @@ import java.net.http.HttpRequest
|
|||||||
import java.net.http.HttpRequest.BodyPublishers
|
import java.net.http.HttpRequest.BodyPublishers
|
||||||
import java.net.http.HttpResponse.BodyHandlers
|
import java.net.http.HttpResponse.BodyHandlers
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.security.MessageDigest
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.jvm.optionals.getOrDefault
|
import kotlin.jvm.optionals.getOrDefault
|
||||||
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val logger = LoggerFactory.getLogger("api")
|
val logger = LoggerFactory.getLogger("api")
|
||||||
val adminRole = Role.Standard(Action.ADMIN)
|
val adminRole = Role.Standard(Action.ADMIN)
|
||||||
@ -104,6 +108,12 @@ fun main(args: Array<String>) {
|
|||||||
it.result(atResponse.accessToken).contentType(ContentType.TEXT_PLAIN)
|
it.result(atResponse.accessToken).contentType(ContentType.TEXT_PLAIN)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
get("/keys") {
|
||||||
|
//for the UI to validate signature and response
|
||||||
|
it.json(
|
||||||
|
Session.jwk()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
before("/api/*") { ctx ->
|
before("/api/*") { ctx ->
|
||||||
@ -127,7 +137,13 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
after("/api/*") {
|
after("/api/*") {
|
||||||
|
|
||||||
it.header("X-Signature", Session.sign(it.body()))
|
val md = MessageDigest.getInstance("SHA-512")
|
||||||
|
md.update((it.result() ?: "").toByteArray())
|
||||||
|
val aMessageDigest = md.digest()
|
||||||
|
|
||||||
|
val outEncoded: String = Base64.getEncoder().encodeToString(aMessageDigest)
|
||||||
|
it.header("X-Checksum", outEncoded)
|
||||||
|
it.header("X-Signature", signPayload(outEncoded))
|
||||||
|
|
||||||
if (appConfig.enforcePayloadEncryption()) {
|
if (appConfig.enforcePayloadEncryption()) {
|
||||||
//todo:, encrypt and set the response back to user
|
//todo:, encrypt and set the response back to user
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import io.ebean.config.DatabaseConfig
|
|||||||
import io.ebean.config.TenantMode
|
import io.ebean.config.TenantMode
|
||||||
import org.bouncycastle.openssl.jcajce.JcaPEMWriter
|
import org.bouncycastle.openssl.jcajce.JcaPEMWriter
|
||||||
import org.bouncycastle.util.io.pem.PemReader
|
import org.bouncycastle.util.io.pem.PemReader
|
||||||
|
import org.jose4j.jwk.JsonWebKey
|
||||||
import org.jose4j.jwk.PublicJsonWebKey
|
import org.jose4j.jwk.PublicJsonWebKey
|
||||||
import org.jose4j.jwk.RsaJsonWebKey
|
import org.jose4j.jwk.RsaJsonWebKey
|
||||||
import org.jose4j.jwk.RsaJwkGenerator
|
import org.jose4j.jwk.RsaJwkGenerator
|
||||||
@ -108,7 +109,7 @@ object Session {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sign(payload: String): String {
|
fun signPayload(payload: String): String {
|
||||||
|
|
||||||
// Create a new JsonWebSignature
|
// Create a new JsonWebSignature
|
||||||
val jws = JsonWebSignature()
|
val jws = JsonWebSignature()
|
||||||
@ -161,6 +162,7 @@ object Session {
|
|||||||
fun currentUser() = currentUser.get().userName
|
fun currentUser() = currentUser.get().userName
|
||||||
fun currentTenant() = currentUser.get().tenant
|
fun currentTenant() = currentUser.get().tenant
|
||||||
fun currentRoles() = currentUser.get().roles
|
fun currentRoles() = currentUser.get().roles
|
||||||
|
fun jwk() = keypair.toParams(JsonWebKey.OutputControlLevel.PUBLIC_ONLY)
|
||||||
|
|
||||||
fun Database.findByEntityAndId(entity: String, id: String): DataModel {
|
fun Database.findByEntityAndId(entity: String, id: String): DataModel {
|
||||||
return find(DataModel::class.java)
|
return find(DataModel::class.java)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user