question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JWT authorization

See original GitHub issue

Good afternoon, please help me implement JWT authorization. Old authorization doesn’t work for apiRouting.

An implementation that works in Route

install(Authentication) {
        jwt {
            verifier(JWTService.verifier)
            validate { credential ->
                JWTPrincipal(credential.payload)
            }
        }
    }

And the implementation, unfortunately, which is written in link is not clear to me. Please tell me how to implement ?

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:7

github_iconTop GitHub Comments

3reactions
sigmanilcommented, Apr 12, 2021

We’ve managed to get JWT authentication working. I don’t really have time to clean it up right now, so this will contain a lot of references to our system, but in case it helps:

First, this function is registered with Ktor:

fun jwt(provider: Authentication.Configuration) {
        provider.apply {
            jwt(name = "user") {
                realm = authSettings.jwtRealm
                verifier(getJwkProvider(authSettings.jwtEndpoint), authSettings.jwtIssuer)
                validate { credentials ->
                    UserPrincipal( //UserPrincipal is a data class inheriting from io.ktor.auth.Principal
                        userId = credentials.payload.subject,
                        email = credentials.payload.claims[ClaimTypes.EMAIL]?.asString(),
                        name = credentials.payload.claims[ClaimTypes.NAME]?.asString(),
                        roles = listOf()
                    )
                }
            }
        }
    }

private fun getJwkProvider(jwkEndpoint: String): JwkProvider {
        return JwkProviderBuilder(URL(jwkEndpoint))
            .cached(10, 24, TimeUnit.HOURS)
            .rateLimited(10, 1, TimeUnit.MINUTES)
            .build()
    }

Then this code is basically what we needed:

val authProvider = JwtProvider()

inline fun NormalOpenAPIRoute.auth(route: OpenAPIAuthenticatedRoute<UserPrincipal>.() -> Unit): OpenAPIAuthenticatedRoute<UserPrincipal> {
    val authenticatedKtorRoute = this.ktorRoute.authenticate("user", "admin") { }
    val openAPIAuthenticatedRoute= OpenAPIAuthenticatedRoute(authenticatedKtorRoute, this.provider.child(), authProvider = authProvider)
    return openAPIAuthenticatedRoute.apply {
        route()
    }
}

data class UserPrincipal(
    val userId: String,
    val email: String?,
    val name: String?,
    val roles: List<String>
) : Principal

class JwtProvider : AuthProvider<UserPrincipal> {
    override val security: Iterable<Iterable<Security<*>>> =
        listOf(listOf(Security(SecuritySchemeModel(
            SecuritySchemeType.http,
            scheme = HttpSecurityScheme.bearer,
            bearerFormat = "JWT",
            name = "jwtAuth"),
            emptyList<Scopes>())))

    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

2reactions
Burtancommented, May 30, 2021

If I find a good way to make sigmanils example generic, I’ll make a PR.

Read more comments on GitHub >

github_iconTop Results From Across the Web

JSON Web Token Introduction - jwt.io
Authorization : This is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the...
Read more >
Using JWT (JSON Web Tokens) to authorize users and protect ...
Arguably one of the largest use cases for JWT is authorization. We can generate a JWT token in the backend that is specific...
Read more >
JWT authorization code flow - RingCentral Developers
JWT credentials are used to obtain an access token by calling the Auth API, and are therefore subject to the same rate limits...
Read more >
JWT Authentication — Best Practices and When to Use
A server built on JWT for authorization will create a JWT when a client logs in. This JWT is signed, so any other...
Read more >
Implementing JWT Authentication in ASP.NET Core 5
JWT is typically used for implementing authentication and authorization in Web applications. Because JWT is a standard, all JWTs are tokens but ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found