Identity Management With Auth0 Using Kotlin I: Authentication

Idorenyin Obong
Devcenter Square Blog
7 min readSep 23, 2017

It is no news what Auth0 brings to the table for developers especially in application of standard security principles in user/identity management. They have definitely lived up to their description as an identity-as-a-service solution that removes the complexity of authentication and authorization for app developers.

We are well aware of the risks that come with identity management hence the existence of Auth0. Don’t quote me wrong, you can definitely manage your users’ identities. But security can be a damaging issue to your product if not handled effectively, remember, it is one of the keys to user retention. There is nothing bad in starting up with a solid authentication service therefore buying more time to design your identity management system, and iterate before integrating.

Auth0 is a good way to start user management in your application

source: https://auth0.com/blog/why-you-should-not-manage-your-users-identities/

Auth0 exposes two APIs for developers to consume in their applications, the authentication and management API. In this first part, we will engage ourselves with the authentication API.

The Authentication API
The authentication API exposes Auth0 identity functionality,through the support of some identity protocols such as OpenID Connect, OAuth, and SAML. Remember, protocols are the rules that govern communication within a network. These protocols define communication standards for the authentication of a user. Auth0’s well manged authentication service can be accessed through their libraries like Lock accessible to both android and ios developers.

Auth0 supports the following types of connections(sources of users) :

  1. Social connections
    This is to authenticate a user with a social provider e.g Facebook, Twitter, Github, Bitbucket, Instagram, etc, name them!
  2. Enterprise connections
    Here, you configure connections like AD, SAML, Office 365 and others so that you can let your users login with them.
  3. Database connection
    Here, users info is stored and managed through their username / password credentials either in an Auth0 Database or in your own store. Using your own store comes with configuring the login, getUser scripts and others.
  4. and Passwordless connections
    Here, you use connections like SMS Login, Email Login and others so that you can let your users login without having to choose yet another password.

Auth0 offers browser-based and native login for mobile apps. Read more about the pros and cons here. We will however focus on the native login in this post.

The Advent of Kotlin
Kotlin on the other hand looks very promising haven been officially announced as an official language for android development earlier this year. Some codebases have already migrated to Kotlin, some are on the verge of doing so. and new android developers may opt for Kotlin because of its simplicity, functional, and procedural nature thus the essence of this post.

In light of the above, we will harness the powers of the authentication API using Kotlin programming language for an android application.

Code Implementation

Create your android project and enable Kotlin support(Android studio 3.0+).

Add dependencies to your build.gradle file.

implementation 'com.auth0.android:lock:2.7.0

Create an account at Auth0 .

Create a new client here by inserting a name, choosing native as client-type and clicking create client.

After creating a client, you will be then faced with a quick-start page. Select android and scroll down to where you have your credentials; the domain name and client id. Copy these credentials to the strings.xml file of your android project.

<string name="com_auth0_client_id">YOUR_AUTH0_CLIENT_ID</string>
<string name="com_auth0_domain">YOUR_AUTH0_DOMAIN</string>

Next we have to enable the password grant-type for our client. Select the settings tab for your client, scroll to the end and select advanced settings. Select grant-types and enable password. Save your changes.

Add Manifest place holders to your manifest file

android {
compileSdkVersion 25
defaultConfig {
applicationId "com.idee.android_auth0_kotlin"
minSdkVersion 15
targetSdkVersion 25
//....
// the code below is the manifest place holder
manifestPlaceholders = [auth0Domain: "@string/com_auth0_domain", auth0Scheme: "https"]

}

Add the LockActivity to your manifest file

<activity
android:name="com.auth0.android.lock.LockActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/Lock.Theme"/>

Then in our MainActivity, we setup Lock and Auth0 objects, authentication callbacks etc.

private lateinit var lock: Lockoverride fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// we initialize the Auth0 object
val auth0 = Auth0(this)
//force Lock to use Auth0’s current authentication pipeline
auth0.setOIDCConformant(true)
// build the lock object
lock
= Lock.newBuilder(auth0, callback).build(this)
// start LockActivity
startActivity(lock.newIntent(this))
}
private val callback = object : AuthenticationCallback() {
override fun onAuthentication(credentials: Credentials) {
//Authenticated

}

override fun onCanceled() {
//User pressed back
}

override fun onError(error: LockException) {
//Exception occurred
}
}

This snippet will present a lock activity to you and will include the connections you enabled .

For social connections, you can enable social connections here. Click on a social provider and you will see a pop-up. You are required to provide app secret keys which can be gotten from any of your selected social provider’s personal account. However, you can leave them blank if you are still in development.

Still on the pop-up, select the client tab and enable it for your client app.

For the database connections, after selecting database connections on your Auth0 dashboard, select an existing database or create a new one , and enable your client app for that database. You can use a custom db if you already have another db hosted somewhere else. However, you will need to provide action scripts. You can check this tutorial for further info on custom db creation.

Remember to request for the Internet permission in the manifest

<uses-permission android:name="android.permission.INTERNET" />

If you are not thrilled by Auth0’s login ui, you can design yours and still authenticate with Auth0.

First, we create and initialize an AuthenticationAPIClient object

val authentication = AuthenticationAPIClient(auth0)

If you are logging in with an email or password, here is a snippet

authentication
.login(“EMAIL_ADDRESS”, “PASSWORD”, “my-database-connection”)
.start(new BaseCallback<Credentials>() {
@Override
public void onSuccess(Credentials payload) {
//Logged in!
}
@Override
public void onFailure(AuthenticationException error) {
//Error!
}
});

And if you want to register, you use this:

authentication
.signUp(“EMAIL_ADDRESS”, “PASSWORD”, “my-database-connection”)
.start(object : BaseCallback<Credentials> {
override fun onSuccess(payload: Credentials) {
//Signed Up & Logged in!
}
fun onFailure(error: AuthenticationException) {
//Error!
}
})

Session Management
After successful authentication, we are provided with three tokens namely;

ID Tokens
This contains user profile information (like the user’s name, email, and so forth)

Access Tokens
This can be any type of token (not necessarily a JWT) and is meant for the API. Its purpose is to inform any other API we intend to call that the bearer of this token has been authorized to access the API and perform specific actions (as specified by the scope that has been granted).

It is important that your API is properly equipped to verify the access tokens to prevent unauthorized access. It is worthy to note that Auth0 also offers this functionality here. You can learn more about access tokens here

Refresh tokens
This carry the information necessary to get a new access token.

Tokens have expiration time which can be changed in the Dashboard > Clients > Settings screen using the JWT Expiration (seconds) field. Also, tokens are signed with different algorithms, to check or update the algorithm your Client uses go to Client Settings > Show Advanced Settings > OAuth > JsonWebToken Signature Algorithm

We need to verify our ID token before we store it and manage sessions.

Ways of verifying an ID Token:
1. We can check to ensure that the issuer of the token matches our Auth0 domain; https://idee.auth0.com/ in my own case.
We can achieve this by introducing the JWTDecode.Android library.

Add the dependencies to your gradle file

implementation 'com.auth0.android:jwtdecode:1.1.1'

In the onAuthentication method overrided by our callback, get your access token and check the issuer.

override fun onAuthentication(credentials: Credentials) {
//Authenticated
val token = credentials.idToken!!
val jwt:JWT? = JWT(token)

if (jwt.getIssuer().equals("https://idee.auth0.com/")){
// it is authentic
} else {
// discard the token
}
}

2. We can check the token audience. The ID token returns the recipients that the JWT is intended for. The value must match the client ID of your Auth0 Client.

if(jwt.audience?.get(0)!!.equals(getString(R.string.com_auth0_client_id))){
// it is authentic
} else {
// discard token
}

3. We can also verify the algorithm used to sign the tokens if it matches the algorithm on your client settings

if (jwt.signature.equals("RS256")){
//RS256 is the default
} else {
// discard it
}

Always verify your tokens

After verifying your ID token, you can now store it into your share preferences. You can always test if the token is expired by using

if (jwt.isExpired(0)){
// it is expired
} else {
// still okay
}

If it is expired, you redirect the user to the login screen again. You should always check whenever a user launches your app.

Wrapping up

Auth0 helps you to:

  • Add authentication with multiple authentication sources, either social like Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, among others, or enterprise identity systems like Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider.
  • Add authentication through more traditional username/password databases and so much more as we will see in part II.

In the second part, we will see how we can manage our users.

Thank you!

--

--