【问题标题】:Ktor Keycloak Acess Token Route ProtectionKtor Keycloak 访问令牌路由保护
【发布时间】:2021-11-04 21:54:16
【问题描述】:

我正在使用通过 keycloak 进行身份验证的服务器。在 keycloak 中,我创建了一个领域,并且能够获得一个访问令牌作为响应。这个访问令牌现在被输入到我的 Ktor 应用程序中。

但是,我不太确定如何以简单的方式保护路线。我希望有一些受保护的路由,其周围有一个authenticate("keycloakOAuth"){} 范围,用于处理验证访问令牌并在访问令牌过期时使用刷新令牌进行刷新。

目前我在 Ktor 中的 keycloak 配置如下:


        authenticate("keycloakOAuth") {
            get("login") {}

            route("/callback") {
                // This handler will be executed after making a request to a provider's token URL.
                handle {
                    val principal = call.authentication.principal<OAuthAccessTokenResponse>()

                    if (principal != null) {
                        val response = principal as OAuthAccessTokenResponse.OAuth2
                        call.respondText { "Access token: ${response.accessToken}" }
                    } else {
                        call.respondText { "NO principal" }
                    }
                }
            }
        }

这很好用,因为当我登录时,我会被发送到 Keycloak 登录页面并且我可以登录。当我登录时,回调执行,我得到了我的访问令牌。

但是,当我尝试保护路线时,会发生一些奇怪的事情。我知道我需要验证传入的 JWT 令牌。但我不知道如何赋予 Ktor 能力。这些例子也没什么帮助,因为它们很模糊。

目前我有这样的事情:


        authenticate("keycloakOAuth") {
            get("/testAuth") {
                val principal = call.authentication.principal<OAuthAccessTokenResponse.OAuth2>()
                if(principal != null) {
                    call.respondText("Authenticated!")
                } else {
                    call.respondText("Unauthenticated...")
                }
            }
        }

但我的应用程序将始终将我发送到登录页面,然后是回调页面,即使我在测试此调用时正在发送 Bearer 令牌。

我的问题是:

如何以需要有效令牌的方式保护路由,使用与 Ktor 相同的语法(如 authenticate(){})。我需要为此配置 JWT 吗?

【问题讨论】:

    标签: kotlin keycloak access-token ktor


    【解决方案1】:

    当您请求authenticate 下的路由之一时,将触发 OAuth 身份验证的完整循环。这是因为 Authentication 插件的设计目的是让客户端发送凭据并为每个请求进行身份验证。出于某种原因,OAuth 集成是在 Authentication 插件之上实现的,因此出现了这种意外行为。

    要解决您的问题,您只能限制 /login 和 /callback 路由。在回调的处理程序中,将用户 ID 和令牌保存在 session 或任何其他存储中以供将来使用。对于其他路由,您可以手动检查用户是否经过身份验证,然后使用存储中的令牌从资源服务器获取受保护的数据。为方便起见,您可以创建一些extension functions 以尽量减少样板代码的数量。不幸的是,没有内置功能可以使其开箱即用。

    您不需要为此配置 JWT。

    【讨论】:

    • 感谢您的详细回答。从现在开始,我将使用会话来获取用户的信息。但是,在验证令牌方面。我怎样才能做到这一点?我看到here 他们使用带有证书的 verifyOffline。但我想知道如何在迄今为止找到的this 的 Java 版本中执行此操作。
    • 我建议阅读 Ktor 文档中关于 JWT 的文章ktor.io/docs/jwt.html。
    猜你喜欢
    • 2020-07-25
    • 2018-07-27
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2020-09-29
    • 2020-12-03
    • 2015-10-15
    相关资源
    最近更新 更多