Security documentation not being generated
See original GitHub issueWe’ve been able to implement JWT-authenticated endpoints through the Ktor-OpenAPI-Generator API, and authentication works - but the generated OpenAPI.json doesn’t contain any information about the security scheme. It should, right?
We have written the following code to tell Ktor-OpenAPI-Generator about the authentication:
val authProvider = JwtProvider();
inline fun NormalOpenAPIRoute.auth(route: OpenAPIAuthenticatedRoute<UserPrincipal>.() -> Unit):
OpenAPIAuthenticatedRoute<UserPrincipal> {
val authenticatedKtorRoute = this.ktorRoute.authenticate { }
var openAPIAuthenticatedRoute= OpenAPIAuthenticatedRoute(authenticatedKtorRoute, this.provider.child(), authProvider = authProvider);
return openAPIAuthenticatedRoute.apply {
route()
}
}
data class UserPrincipal(val userId: String, val email: String?, val name: String?) : Principal
class JwtProvider : AuthProvider<UserPrincipal> {
override val security: Iterable<Iterable<Security<*>>> =
listOf(listOf(Security(SecuritySchemeModel(SecuritySchemeType.openIdConnect, scheme = HttpSecurityScheme.bearer, bearerFormat = "JWT", name = "JWT"), Scopes.values().toList())))
override suspend fun getAuth(pipeline: PipelineContext<Unit, ApplicationCall>): UserPrincipal {
return pipeline.context.authentication.principal() ?: throw RuntimeException("No JWTPrincipal")
}
override fun apply(route: NormalOpenAPIRoute): OpenAPIAuthenticatedRoute<UserPrincipal> {
val authenticatedKtorRoute = route.ktorRoute.authenticate { }
return OpenAPIAuthenticatedRoute(authenticatedKtorRoute, route.provider.child(), this)
}
}
enum class Scopes(override val description: String) : Described {
Profile("Some scope")
}
In our Application.apirouting, we wrap the required paths with auth{}, and make sure we use the routing functions from com.papsign.ktor.openapigen.route.path.auth.* in those cases. We are able to access the authenticated user through the principal()-function. An example:
auth {
route("/user") {
get<Unit, List<User>, UserPrincipal> {
val principal = principal()
log.info("principal1 ${principal.userId}")
log.info("principal1 ${principal.email}")
respond(registry.userRepository.retrieveAllUsers())
}
}
}
Everything seems to work fine for actual use - but as mentioned, we’re not finding any information about the security scheme in the generated openapi.json. 😦
We are calling addModules(authProvider)
as part of the installation of OpenAPIGen, but we’re under the impression this isn’t working as intended. (We are supposed to add it as a module, right?) Here, we’re ending up in the object com.papsign.ktor.openapigen.modules.handlers.AuthHandler:
package com.papsign.ktor.openapigen.modules.handlers
import com.papsign.ktor.openapigen.OpenAPIGen
import com.papsign.ktor.openapigen.model.operation.OperationModel
import com.papsign.ktor.openapigen.model.security.SecurityModel
import com.papsign.ktor.openapigen.modules.ModuleProvider
import com.papsign.ktor.openapigen.modules.ofType
import com.papsign.ktor.openapigen.modules.openapi.OperationModule
import com.papsign.ktor.openapigen.modules.providers.AuthProvider
object AuthHandler: OperationModule {
override fun configure(apiGen: OpenAPIGen, provider: ModuleProvider<*>, operation: OperationModel) {
val authHandlers = provider.ofType<AuthProvider<*>>()
val security = authHandlers.flatMap { it.security }.distinct()
operation.security = security.map { SecurityModel().also { sec ->
it.forEach { sec[it.scheme.name] = it.requirements }
} }
apiGen.api.components.securitySchemes.putAll(security.flatMap { it.map { it.scheme } }.associateBy { it.name })
}
}
Here, in the configure method, provider seems to contain our authProvider object, but it isn’t returned from the “provider.ofType<AuthProvider<*>>()” call. But at this point we’re a bit uncertain if we’re barking up the wrong tree, and if we’re not, why our AuthProvider isn’t recognized as one by ofType…
We’re not sure if this is a bug in OpenAPIGen or just something we haven’t understood about how to use the framework. Any help would be greatly appreciated.
Issue Analytics
- State:
- Created 3 years ago
- Comments:19 (3 by maintainers)
Top GitHub Comments
Actually I’m mistaken, my latest KType changes have not been released yet - but I will take a look at it regardless as I have the same problem.
Hello, I actually wrote that change to KType and must have missed something. I will take a look at it shortly (as I noticed this problem myself with our my project). A failing test would be helpful.