Saturday, September 15. 2018

Today's entry presents a keycloak integration for an android application. Keycloak is an open-source project that offers Single Sign-On and access management for modern applications and services, and it has been used before in the blog. It is based on standards (like OpenID Connect and SAML) and provides some adapters for different programming languages and application platforms. Previously any integration between a mobile application and keycloak used an embedded browser to perform the login, but now that solution is a no-go. Google started to avoid this technique and recommend custom URLs long time ago. I have almost zero experience in mobile development (sorry for that) but I wanted to test this solution by myself anyway.

The idea is simple, as a mobile program is a client-side application I decided to use a public profile (similar situation to the one in browser-side JavaScript). I think that having a password in the client is almost the same than using none, it gives no extra security. The application is going to be a java one (it is just a PoC, so using kotlin was an extra effort for me).

First creating the public keycloak client for the application is needed. The application will use a weird URL keycloak://keycloaksample/.

Starting with the android application, the custom URL should be defined in the AndroidManifest.xml, in my case for the .MainActivity.

With this configuration the .MainActivity will be called when the browser receives the keycloak://keycloaksample/ URL from the SSO server. That feature will be used to use the external browser to do the login and the logout. So a button will initiate the browser which will go to the authentication URL.

If you see, the URL is created with the application URL as the redirect_uri. The idea is the login button starts the default browser with the keycloak authentication URL (android starts the app associated to an http(s) scheme), the user performs the login with it, and after that the server redirects the browser to the application URL, which starts the activity inside our app.

Now it's the time to follow the OIDC specification an get the code returned from the server and, with it, obtain the access and refresh token. In the onCreate of the activity a LoginTask starts a thread that executes the call to the token endpoint.

And finally, with the JSON data returned by the server, a TokenResponse object is created. For that I used the jjwt project which can parse the different JWT tokens returned by the server. This way the application can obtain the token information and present the user info.

Mainly this is the idea about the custom URL technique, android can associate a weird URL with the application and normal browser login is used to perform the SSO login. After that the OIDC calls are used to get the tokens and use them. My application also exemplifies how to do the logout, refresh the token and call another web service (userinfo) using the access token. But that is just development that uses the TokenResponse object initially created in the login.

Here I present a video, first I log into the application, thanks to custom URLs the browser is used to do that. Then the token information is shown and it is used to call the OIDC userinfo endpoint (information of the user). As you see the SSO is in place and I can reach the keycloak console without login again. Then I wait the access token to expire (60 seconds) and I refresh it (refresh_token action in the OIDC token endpoint). Finally I perform the logout which is a global logout too.

Your browser doesn't support the video tag. See this entry for more information about how to see the videos in this blog. You can download the file instead.

And that is all. I wanted to test the custom URL technique in an mobile application and I decided to use android (iOS is a complete unknown for me, but I suppose the same idea can be used for that platform). The application is very simple and just uses the jjwt project out of the default android API. This is just a PoC so it can be extended and/or improved a lot (for example not using fixed URLs and keys, calling the well-known OIDC address and the JWKs certificate endpoints is a better solution). Please also take in mind that I never develop for mobile, so just use the app as an example, surely things can be done much better. The KeycloakSample application can be download from here, hope it helps to someone else.