【问题标题】:Multiple urlProviders on the same oauth setting in ktor with keycloak具有 keycloak 的 ktor 中相同 oauth 设置上的多个 urlProviders
【发布时间】:2021-06-10 13:37:11
【问题描述】:

我正在制作一个使用 keycloak 作为身份验证的 ktor Web 应用程序。

val keycloakProvider = OAuthServerSettings.OAuth2ServerSettings(
    name = CLIENT_NAME,
    authorizeUrl = KEYCLOAK_AUTH,
    accessTokenUrl = KEYCLOAK_TOKEN,
    clientId = CLIENT_ID,
    clientSecret = CLIENT_SECRET,
    accessTokenRequiresBasicAuth = false,
    requestMethod = HttpMethod.Post, // must POST to token endpoint
    defaultScopes = listOf("roles")
)

我想要保护多个端点,但重定向 URI 只能设置为一个 URL,在下面的示例中为 /login/oauth/secret

    install(Authentication)
    {
        oauth("secretOAuth") {
            client = HttpClient(Apache)
            providerLookup = { keycloakProvider }
            urlProvider = { "/secret" }
        }
        oauth("keycloakOAuth") {
            client = HttpClient(Apache)
            providerLookup = { keycloakProvider }
            urlProvider = { "/login/oauth" }
        }
    }

像上面的示例那样创建多个这样的身份验证路径是否有意义,还是不好的做法? /login/oauth/secret 指向以下路由:

    authenticate(keycloakOAuth) {
        get("/login/oauth") {
            val principal = call.authentication.principal<OAuthAccessTokenResponse.OAuth2>()
                ?: throw Exception("No principal was given")

            createSession(principal)
            call.respondRedirect("/")
        }
    }

    authenticate(secretOAuth){
        get("/secret")
        {
            val principal = call.authentication.principal<OAuthAccessTokenResponse.OAuth2>()
                ?: throw Exception("No principal was given")
            createSession(principal)
            call.respondHtml {
                body{
                    h1{
                            +"You accessed secure page!"
                    }
                }
            }
        }
    }

功能方面,它可以工作,当用户未登录时,它会通过登录窗口提示他们,否则他们会看到秘密/他们的会话被创建,但我不确定这是否是正确的做法它。真的没有办法根据访问的URI更改urlProvider吗?因为那样我将不得不为每个受保护的端点进行身份验证,这可能有点太多了。

【问题讨论】:

    标签: authentication web oauth-2.0 keycloak ktor


    【解决方案1】:

    在您的场景中,为同一个提供者配置多个身份验证配置是多余的,因为客户端可以获取任何访问令牌。我建议使用authenticate 块来获取访问令牌并将其保存在某处。您可以对“秘密”资源使用通常的路由,您可以在其中检查具有访问令牌的用户。

    routing {
        authenticate("keycloakOAuth") {
            get("/login") {
                // The endpoint for user login
            }
    
            get("/callback") {
                val principal = call.authentication.principal<OAuthAccessTokenResponse.OAuth2>()
    
                if (principal != null) {
                    // Save access token (principal.accessToken) for further use
                } else {
                    // Something went wrong
                }
            }
        }
        
        get("/secret") {
            if (!hasToken()) {
                call.respondRedirect("/login")
            }
        }
    }
    

    【讨论】:

    • 好的,这解决了我一半的问题。我想要的是 keycloak 在登录后将我重定向到 /secret 端点。这在 ktor 中如何工作,如何动态传递任何秘密端点的重定向?我尝试在安装块中定义多个 oauth 的原因是我没有找到任何其他方式在身份验证后将用户重定向到该特定端点。
    • 您可以将用户重定向到/callback 处理程序中的任何位置。
    • 嗯,好的,感谢您的快速响应。所以我会用这行call.respondRedirect("/")重定向用户。但是我不确定如何在回调处理程序中获取原始 uri,例如 /secret 。它可以在调用对象中访问吗?因为我似乎找不到它。
    • 很遗憾,我找不到获取原始 URI 的方法。您可能可以将此信息保存在客户端的会话 ktor.io/docs/sessions.html 中,稍后将其用于重定向。
    猜你喜欢
    • 2021-05-27
    • 2012-08-30
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 2021-07-02
    • 2015-11-22
    • 1970-01-01
    相关资源
    最近更新 更多