Skip to content

Instantly share code, notes, and snippets.

@miere
Created June 6, 2022 00:44
Show Gist options
  • Save miere/70b50790880f37b60baed63011b12b79 to your computer and use it in GitHub Desktop.
Save miere/70b50790880f37b60baed63011b12b79 to your computer and use it in GitHub Desktop.
JWT with Kos + Vert.x
package nct.engineering.security
import injector.Exposed
import kos.api.WebServerEventListener
import org.slf4j.LoggerFactory
@Exposed
class SecurityConfig: WebServerEventListener {
private val logger = LoggerFactory.getLogger(javaClass)
override fun on(event: WebServerEventListener.BeforeDeployWebServerEvent) {
val interceptor = event.kosContext.implementationLoader
.instanceOfOrFail(SecurityRequestInterceptor::class.java)
logger.info("Registering the JWT request interceptor...")
event.router.intercept(interceptor)
}
}
package nct.engineering.security
import injector.Singleton
import io.vertx.core.Handler
import io.vertx.core.http.HttpHeaders.AUTHORIZATION
import io.vertx.core.http.HttpServerRequest
import io.vertx.ext.auth.PubSecKeyOptions
import io.vertx.ext.auth.authentication.AuthenticationProvider
import io.vertx.ext.auth.authentication.TokenCredentials
import io.vertx.ext.auth.jwt.JWTAuth
import io.vertx.ext.auth.jwt.JWTAuthOptions
import kos.api.KosContext
import kos.api.RequestInterceptor
@Singleton
class SecurityRequestInterceptor(
val kosContext: KosContext
): RequestInterceptor {
private val config: JWTAuthOptions = JWTAuthOptions()
.addPubSecKey(
PubSecKeyOptions()
.setAlgorithm("RS256")
.setBuffer("""-----BEGIN CERT...-END CERTIFICATE-----""")
)
private val provider: AuthenticationProvider = JWTAuth.create(kosContext.defaultVertx, config)
override fun handle(request: HttpServerRequest, next: Handler<HttpServerRequest>) {
if (request.uri() == "/healthz") {
next.handle(request)
return
}
val foundHeader = request.getHeader(AUTHORIZATION)
if (foundHeader == null) {
request.sendUnauthorised()
return
}
val (_, token) = foundHeader.split(" ")
performJwtValidation(token, request, next)
}
private fun performJwtValidation(token: String, request: HttpServerRequest, next: Handler<HttpServerRequest>) {
val credentials = TokenCredentials(token)
provider.authenticate(credentials)
.onFailure {
it.printStackTrace()
request.sendUnauthorised()
}
.onSuccess { next.handle(request) }
}
private fun HttpServerRequest.sendUnauthorised() =
this.response().apply {
statusCode = 401
send()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment