kotlin-multiplatform-keycloak-client 1.0.2 indexed Secure apps with Keycloak: build client with optional client-secret, generate auth-code or implicit login URLs, fetch/refresh tokens, request RPTs via ticket or client-id, retrieve user info.
Bring this to kpkg
This library is indexed from the KMP ecosystem and already resolves through kpkg.dev's Maven Central proxy. Maintainers can verify the namespace and publish future versions to kpkg for free hosting, real download stats, and signed-provenance pages.
Publishing coming soonMetadata
Owner klsoft-mobile
Stars 0
Used by —
Health —
License MIT License
Latest 1.0.2
Repository github.com/klsoft-mobile/kotlin-multiplatform-keycloak-client
Updated 2026-02-06 Readme Changelog KOTLIN-MULTIPLATFORM-KEYCLOAK-CLIENT
A Kotlin Multiplatform library that can be used to secure applications with Keycloak. It is typically used in conjunction with RESTful web service APIs.
See also:
YII2-JWT-AUTH - The package provides a Yii 2 authentication method based on a JWT token
YII2-KEYCLOAK-AUTHZ - The package provides Keycloak authorization for the web service APIs of Yii 2
YII3-JWT-AUTH - The package provides a Yii 3 authentication method based on a JWT token
YII3-KEYCLOAK-AUTHZ - The package provides Keycloak authorization for the web service APIs of Yii 3
Supported platforms
Installation
[versions]
keycloakClient = "1.0.2"
serializationJson = "1.10.0"
[libraries]
keycloak-client = { module = "io.github.klsoft-mobile.kotlin.multiplatform:keycloak-client" , version.ref = "keycloakClient" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json" , version.ref = "serializationJson" }
implementation(libs.keycloak.client)
implementation(libs.kotlinx.serialization.json)
Example of initializing a KeycloakClient
import klsoft.kotlin.multiplatform.keycloakclient.KeycloakClient
@Provides
fun provideKeycloakClient () : KeycloakClient = KeycloakClient.Builder()
.setClientSecret("Keycloak client secret" )
.build(
"http://mykeycloak.com/realms/myrealm" ,
"Keycloak client ID" ,
"http://mysite.com/login" );
Example of creating an Authorization Code flow URL
import klsoft.kotlin.multiplatform.keycloakclient.KeycloakClient
class AuthRepositoryImpl @Inject constructor (private val keycloakClient: KeycloakClient) : AuthRepository {
override fun loginUrl () : String {
return keycloakClient.createAuthorizationCodeLoginUrl()
}
}
Example of creating an Implicit flow URL
import klsoft.kotlin.multiplatform.keycloakclient.KeycloakClient
class AuthRepositoryImpl @Inject constructor (private val keycloakClient: KeycloakClient) : AuthRepository {
override fun loginUrl () : String {
return keycloakClient.createImplicitLoginUrl()
}
}
Example of fetching a token using an Authorization Code
AuthScreen.kt
{
Column(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context .
WebView(context).apply {
settings.javaScriptEnabled =
loadUrl(loginUrl)
webViewClient = : WebViewClient() {
{
url.toUri().getQueryParameter( )?.let { code ->
codeReceived(code)
}
}
}
}
}
)
}
}
AuthRepositoryImpl.kt
ApiResult.kt
Example of fetching a token using client credentials
This method can only be used by confidential clients. Make sure that both the Client authentication and Service accounts roles options are ON in Keycloak
Example of refreshing a token
Example of fetching a Requesting Party Token using a permission ticket
Example of fetching a Requesting Party Token by the client ID
Example of fetching a user information
Example of a logout
@Composable
private
fun Content (
loginUrl: String ,
codeReceived: (String ) . Unit ,
innerPadding: PaddingValues
)
true
object
override
fun onPageStarted (
view: WebView ,
url: String ,
favicon: Bitmap ?
)
"code"
import klsoft.kotlin.multiplatform.keycloakclient.KeycloakClient
class AuthRepositoryImpl @Inject constructor (private val keycloakClient: KeycloakClient) : AuthRepository {
override suspend fun fetchTokenByAuthorizationCode (code: String ) : ApiResult<Tokens, ApiError> {
val responseResult = keycloakClient.fetchTokenByAuthorizationCode(code)
if (responseResult.responseStatusCode == 200 ) {
val data = responseResult.data
if (data .containsKey(ACCESS_TOKEN) &&
data .containsKey(REFRESH_TOKEN)) {
return ApiResult.success(Tokens(
data .getValue(ACCESS_TOKEN).jsonPrimitive.content,
data .getValue(REFRESH_TOKEN).jsonPrimitive.content))
}
} else if (responseResult.responseStatusCode == 401 ) {
} else {
}
}
}
sealed class ApiResult <out T, out E > {
data class Success <T >(val result: T) : ApiResult<T, Nothing >()
data class Error <E >(val error: E) : ApiResult<Nothing , E>()
companion object {
fun <T> success (value: T ) : Success<T> = Success(value)
fun <E> error (error: E ) : Error<E> = Error(error)
}
}
import klsoft.kotlin.multiplatform.keycloakclient.KeycloakClient
class AuthRepositoryImpl @Inject constructor (private val keycloakClient: KeycloakClient) : AuthRepository {
override suspend fun fetchTokenByClientCredentials () : ApiResult<Tokens, ApiError> {
val responseResult = keycloakClient.fetchTokenByClientCredentials()
if (responseResult.responseStatusCode == 200 ) {
val data = responseResult.data
if (data .containsKey(ACCESS_TOKEN))) {
return ApiResult.success(Tokens(
data .getValue(ACCESS_TOKEN).jsonPrimitive.content,
null ))
}
} else if (responseResult.responseStatusCode == 401 ) {
} else {
}
}
}
import klsoft.kotlin.multiplatform.keycloakclient.KeycloakClient
class AuthRepositoryImpl @Inject constructor (private val keycloakClient: KeycloakClient) : AuthRepository {
override suspend fun refreshToken (refreshToken: String ) : ApiResult<Tokens, ApiError> {
val responseResult = keycloakClient.refreshToken(refreshToken)
if (responseResult.responseStatusCode == 200 ) {
val data = responseResult.data
if (data .containsKey(ACCESS_TOKEN) &&
data .containsKey(REFRESH_TOKEN)) {
return ApiResult.success(Tokens(
data .getValue(ACCESS_TOKEN).jsonPrimitive.content,
data .getValue(REFRESH_TOKEN).jsonPrimitive.content))
}
} else if (responseResult.responseStatusCode == 401 ) {
} else {
}
}
}
import klsoft.kotlin.multiplatform.keycloakclient.KeycloakClient
class AuthRepositoryImpl @Inject constructor (private val keycloakClient: KeycloakClient) : AuthRepository {
override suspend fun fetchRequestingPartyTokenByPermissionTicket (
accessToken: String ,
permissionTicket: String ) : ApiResult<Tokens, ApiError> {
val responseResult = keycloakClient.fetchRequestingPartyTokenByPermissionTicket(
accessToken,
permissionTicket)
if (responseResult.responseStatusCode == 200 ) {
val data = responseResult.data
if (data .containsKey(ACCESS_TOKEN) &&
data .containsKey(REFRESH_TOKEN)) {
return ApiResult.success(Tokens(
data .getValue(ACCESS_TOKEN).jsonPrimitive.content,
data .getValue(REFRESH_TOKEN).jsonPrimitive.content))
}
} else if (responseResult.responseStatusCode == 401 ) {
} else {
}
}
}
import klsoft.kotlin.multiplatform.keycloakclient.KeycloakClient
class AuthRepositoryImpl @Inject constructor (private val keycloakClient: KeycloakClient) : AuthRepository {
override suspend fun fetchRequestingPartyTokenByClientId (accessToken: String ) : ApiResult<Tokens, ApiError> {
val responseResult = keycloakClient.fetchRequestingPartyTokenByClientId(accessToken)
if (responseResult.responseStatusCode == 200 ) {
val data = responseResult.data
if (data .containsKey(ACCESS_TOKEN) &&
data .containsKey(REFRESH_TOKEN)) {
return ApiResult.success(Tokens(
data .getValue(ACCESS_TOKEN).jsonPrimitive.content,
data .getValue(REFRESH_TOKEN).jsonPrimitive.content))
}
} else if (responseResult.responseStatusCode == 401 ) {
} else {
}
}
}
import klsoft.kotlin.multiplatform.keycloakclient.KeycloakClient
class AuthRepositoryImpl @Inject constructor (private val keycloakClient: KeycloakClient) : AuthRepository {
override suspend fun fetchUserInfo (accessToken: String ) : ApiResult<UserInfo, ApiError> {
val responseResult = keycloakClient.fetchUserInfo(accessToken)
if (responseResult.responseStatusCode == 200 ) {
val data = responseResult.data
} else if (responseResult.responseStatusCode == 401 ) {
} else {
}
}
}
import klsoft.kotlin.multiplatform.keycloakclient.KeycloakClient
class AuthRepositoryImpl @Inject constructor (private val keycloakClient: KeycloakClient) : AuthRepository {
override suspend fun logout (refreshToken: String ) : ApiResult<Unit , ApiError> {
val responseResult = keycloakClient.logout(refreshToken)
if (responseResult.responseStatusCode == 204 ) {
return ApiResult.success(Unit )
} else if (responseResult.responseStatusCode == 401 ) {
} else {
}
}
}
Related libraries Surfaced from shared tags and platforms — no rankings paid for.
trailbase ★ 5.4k
trailbaseio Single-executable open backend delivering sub-millisecond REST and realtime APIs, multi-database support, WASM runtime for extensibility, geospatial queries, SSR, built-in auth and admin UI. Shared: authentication MediaPlayer-KMP ★ 302
KhubaibKhan4 Enables seamless YouTube video and audio playback across multiple platforms, integrating with JetBrains Compose Multiplatform. Features include authentication tokens, event handling, and reels view support. Shared: authentication kotlin-multiplatform-oidc ★ 153
kalinjul Lightweight implementation of OpenID Connect/OAuth 2.0 supporting Authorization Code Grant Flow, discovery, PKCE, and simple JWT parsing. Includes Android, iOS, desktop support, and OkHttp/Ktor integration. Shared: authentication KotlinMultiplatformAuth ★ 82
sunildhiman90 Facilitates multi-platform authentication with Google Sign-In across Android, iOS, Desktop, and Web. Includes GoogleSignInButton composable for easy integration and future support plans for additional providers. Shared: authentication vck ★ 69
a-sit-plus Implements verifiable credentials for issuing, presentation, and validation across various applications, supporting W3C and ISO standards, ARIES protocols, OpenID, and customizable cryptographic operations. Shared: authentication lokksmith ★ 45
svenjacobs Opinionated library streamlining OpenID Connect Authorization Code Flow implementation with PKCE. Features intuitive API, sensible defaults, and advanced configurability, prioritizing secure standards. Shared: authentication