Skip to content

Commit 1d27baf

Browse files
Oleksandr Dzhychkoslisson
authored andcommitted
chore(model-server): deduplicate authorization logic
The logic determining the verifier was a duplicate of the logic used in the additional validation. The logic from the validation (aka `ModelixAuthorizationConfig,nullIfInvalid`) is also used elsewhere. For example, it is used in the workspaces through the modelix-authorization lib. So it was reused in a custom verifier. Calling `ModelixAuthorizationConfig.nullIfInvalid` again in `validate` is redundant. It is now only used to create a custom principal object.
1 parent c1a8da5 commit 1d27baf

File tree

1 file changed

+24
-16
lines changed

1 file changed

+24
-16
lines changed

authorization/src/main/kotlin/org/modelix/authorization/AuthorizationPlugin.kt

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ package org.modelix.authorization
1818

1919
import com.auth0.jwt.JWT
2020
import com.auth0.jwt.algorithms.Algorithm
21+
import com.auth0.jwt.exceptions.JWTVerificationException
22+
import com.auth0.jwt.interfaces.DecodedJWT
23+
import com.auth0.jwt.interfaces.JWTVerifier
2124
import com.google.common.cache.CacheBuilder
2225
import io.ktor.http.HttpStatusCode
2326
import io.ktor.server.application.Application
@@ -80,31 +83,18 @@ object ModelixAuthorization : BaseRouteScopedPlugin<IModelixAuthorizationConfig,
8083
} else {
8184
// "Authorization: Bearer ..." header is provided in the header by OAuth proxy
8285
jwt(MODELIX_JWT_AUTH) {
83-
val jwkProvider = config.getJwkProvider()
84-
val jwtAlgorithm = config.getJwtSignatureAlgorithmOrNull()
85-
// If JWK URI and JWT algorithm is configured only use the configured algorithm.
86-
// This is the case if MODELIX_JWK_URI and MODELIX_JWK_KEY_ID are configured.
87-
if (jwtAlgorithm != null) {
88-
verifier(getVerifierForSpecificAlgorithm(jwtAlgorithm))
89-
} else if (jwkProvider != null) {
90-
verifier(jwkProvider)
91-
} else {
92-
error("Either an JWT algorithm or a JWK URI must be configured.")
93-
}
86+
verifier(config.getVerifier())
9487
challenge { _, _ ->
9588
call.respond(status = HttpStatusCode.Unauthorized, "No or invalid JWT token provided")
9689
// login and token generation is done by OAuth proxy. Only validation is required here.
9790
}
9891
validate {
9992
try {
100-
val token = jwtFromHeaders()
101-
if (token != null) {
102-
return@validate config.nullIfInvalid(token)?.let { AccessTokenPrincipal(it) }
103-
}
93+
jwtFromHeaders()?.let(::AccessTokenPrincipal)
10494
} catch (e: Exception) {
10595
LOG.warn(e) { "Failed to read JWT token" }
96+
null
10697
}
107-
null
10898
}
10999
}
110100
}
@@ -203,3 +193,21 @@ class ModelixAuthorizationPluginInstance(val config: ModelixAuthorizationConfig)
203193
}
204194
}
205195
}
196+
197+
/**
198+
* Returns an [JWTVerifier] that wraps our common authorization logic,
199+
* so that it can be configured in the verification with Ktor's JWT authorization.
200+
*/
201+
internal fun ModelixAuthorizationConfig.getVerifier() = object : JWTVerifier {
202+
override fun verify(token: String?): DecodedJWT {
203+
val jwt = JWT.decode(token)
204+
return verify(jwt)
205+
}
206+
207+
override fun verify(jwt: DecodedJWT?): DecodedJWT {
208+
if (jwt == null) {
209+
throw JWTVerificationException("No JWT provided.")
210+
}
211+
return this@getVerifier.nullIfInvalid(jwt) ?: throw JWTVerificationException("JWT invalid.")
212+
}
213+
}

0 commit comments

Comments
 (0)