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?
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;
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
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/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With