iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
0
Mobile Development

老姐好像要用 Kotlin 寫專案,能撐30天嗎?系列 第 16

補班前夜的第十六天:把 Ktor 綁上 Keycloak 大船

  • 分享至 

  • xImage
  •  

大口深呼吸,現在要開始把 Ktor 綁上 Keycloak 大船了。

老姐還笑我太緊張,都不知道我這幾天查了多少資料。

官網的範例看起來沒有問題,就是少了些詳細說明,幸好憑經驗多少能補足。 https://ktor.io/docs/authentication-oauth.html
https://ithelp.ithome.com.tw/upload/images/20200925/20129197pwTTbITzdf.png

先在 build.gradle 加上相關 Library 。

    implementation "io.ktor:ktor-auth:$ktor_version"
    implementation "io.ktor:ktor-client-apache:$ktor_version"
    implementation "io.ktor:ktor-auth-jwt:$ktor_version"

Application.module 裡加上 keycloakOAuth 程式碼。

install(Authentication) {
        oauth("keycloakOAuth") {
            client = HttpClient(Apache)
            providerLookup = { OAuthServerSettings.OAuth2ServerSettings(
                    name = "keycloak",
                    authorizeUrl = "$authorizeUrl",
                    accessTokenUrl = "$accessTokenUrl",
                    clientId = "$clientId",
                    clientSecret = "$clientId",
                    accessTokenRequiresBasicAuth = false,
                    requestMethod = HttpMethod.Post,
                    defaultScopes = listOf("roles")
            )}
            urlProvider = {
                redirectUrl("/", false)
            }
        }
    }

轉向網址的程式碼因為可能會多次用到,獨立出來寫成 redirectUrl 函式 。

private fun ApplicationCall.redirectUrl(t: String, secure: Boolean = true): String {
    val hostPort = request.host()!! + request.port().let { port -> if (port == 80) "" else ":$port" }
    val protocol = when {
        secure -> "https"
        else -> "http"
    }
    return "$protocol://$hostPort$t"
}

authorizeUrlaccessTokenUrl 可在昨天新增的 realm setting Turtlesoup 點下 Endpoints 的 OpenID Endpoint Configuration 打開網頁拿到。

https://ithelp.ithome.com.tw/upload/images/20200925/20129197O8A4NHHi58.png

clientId 可在昨天新增的 Clients soup bowl 裡昨天拿到,但 clientSecret 要把 Access Type 改成 confidential 才能有 Credentials 分頁。

https://ithelp.ithome.com.tw/upload/images/20200925/201291979ehq6EYbPd.png

https://ithelp.ithome.com.tw/upload/images/20200925/20129197jBddHVg3hF.png

接著設定登入網址,登入後要拿哪些資料晚點再處理。

routing {
        authenticate("keycloakOAuth") {
            route("/login") { // Redirects for authentication
                param("error") {
                    handle {
                        call.respond(call.parameters.getAll("error").orEmpty())
                    }
                }

                handle {
                    val principal = call.authentication.principal<OAuthAccessTokenResponse.OAuth2>()
                    if (principal != null) {
                        val token = JWT.decode(principal.accessToken)
                        //todo
                    } else {
                        call.respond(HttpStatusCode.Unauthorized)
                    }
                }
            }
        }
        ...

現在打開看看 http://localhost:8080/login ,好,成功顯示登入畫面!
因為有開啟註冊功能所以也能看到註冊按鈕!

https://ithelp.ithome.com.tw/upload/images/20200925/201291974Y2NalDgqn.png

https://ithelp.ithome.com.tw/upload/images/20200925/201291974khlDwMJ0K.png

如果要加入其他 OpenID ,比如 Google ,還是要去各服務開啟設定,再填進來。

https://ithelp.ithome.com.tw/upload/images/20200925/20129197tQdxtnAsVF.png

這個登入網頁 app 和網站是共用的,也就是說,使用 Keycloak 省去的是設計畫面和傳統帳號密碼流程的時間。

至於 Api 和登入狀態的關係,還是要另外花時間處理。

明天是可怕的補班日,不知道還有沒有精力對付專案。

本次鐵人賽的作品在放進更多內容後已經成書,書名是《老姐要用Kotlin寫專案:從 Server 到 Android APP 的開發生存日記》,歡迎購買唷。https://www.tenlong.com.tw/products/9789864348978


上一篇
抓住稻草的第十五天:Docker & Keycloak 設定
下一篇
改善程式的第十七天:Kotlin Null Safety 別名「消滅 Null Check Conditions 計畫」
系列文
老姐好像要用 Kotlin 寫專案,能撐30天嗎?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言