Created
June 6, 2022 00:44
-
-
Save miere/70b50790880f37b60baed63011b12b79 to your computer and use it in GitHub Desktop.
JWT with Kos + Vert.x
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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