Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to keep the OAuth client credentials on Android

Tags:

android

oauth

I have an Android application that interacts with a WebAPI through OAuth security. For getting the access token, I need to send the OAuth credentials (i.e. client id and client secret) in the header of the request. My question is, where should I keep these 2 values (client id and client secret) for the application to use it when required. Currently, I have just hardcoded it in the call. Is it safe to keep these in the strings.xml file?

like image 885
Abhinav Nair Avatar asked Mar 31 '16 04:03

Abhinav Nair


3 Answers

Hidden in BuildConfigs

First, create a file apikey.properties in your root directory with the values for different secret keys:

CONSUMER_KEY=XXXXXXXXXXX

CONSUMER_SECRET=XXXXXXX

To avoid these keys showing up in your repository, make sure to exclude the file from being checked in by adding to your .gitignore file:

apikey.properties

Next, add this section to read from this file in your app/build.gradle file. You'll also create compile-time options that will be generated from this file by using the buildConfigField definition:

def apikeyPropertiesFile = rootProject.file("apikey.properties")
def apikeyProperties = new Properties()
apikeyProperties.load(new FileInputStream(apikeyPropertiesFile))

android {

  defaultConfig {

     // should correspond to key/value pairs inside the file   
    buildConfigField("String", "CONSUMER_KEY", apikeyProperties['CONSUMER_KEY'])
    buildConfigField("String", "CONSUMER_SECRET", apikeyProperties['CONSUMER_SECRET'])
  }
}

You can now access these two fields anywhere within your source code with the BuildConfig object provided by Gradle:

// inside of any of your application's code
String consumerKey = BuildConfig.CONSUMER_KEY;
String consumerSecret = BuildConfig.CONSUMER_SECRET;
like image 121
Victory Avatar answered Oct 05 '22 05:10

Victory


It seems you should be using a different OAuth Flow. As you experinced, Native Apps can't keep secrets. You can read about recommendations for OAuth and native apps here. https://www.rfc-editor.org/rfc/rfc8252

Your probably want to look at Authorization Code Flow with PKCE. Here you accept the fact that a native apps can't keep a secret. You can find a relatively simple explanation of the flow here: https://auth0.com/docs/flows/concepts/auth-code-pkce

As an alternative you can look at dyanmic client registration (https://www.rfc-editor.org/rfc/rfc7591) but it might be overkill for your application. Using dynamic client registration you won't have to hard code the client secret

like image 28
Simon Avatar answered Oct 05 '22 05:10

Simon


If you are concerned about security then you can save the data in SharedPreference by encrypting and saving encryption keys in Android Keystore.

The Keystore is not used directly for storing application secrets such as password, however, it provides a secure container, which can be used by apps to store their private keys, in a way that’s pretty difficult for malicious (unauthorised) users and apps to retrieve.

Here is nice tutorial for creating keystores. http://www.androidauthority.com/use-android-keystore-store-passwords-sensitive-information-623779/

like image 26
crashOveride Avatar answered Oct 05 '22 04:10

crashOveride