I am trying to require user authentication through Keyguard Manager for an Android app as part of a flow. This means that user must be authenticated to go through the flow. This is accomplished by starting a Keyguard Manager createConfirmDeviceCredentialIntent generated activityForResult and receiving an activityResult from it.
I want to test that flow automatically. This causes a problem because my automated test isn't able to authenticate itself(i.e. enter swipe pattern or enter PIN). How can I get my test to automatically pass this to put the test environment into an authenticated state? Can I mock some function in the Keyguard Manager to automatically pass the authentication check?
Keyguard Manager
createConfirmDeviceCredentialIntent
The solution to this was more abstraction. Previously I had been doing encrpytion and decryption through static methods. I switched to using an Encryptor and Decryptor object which had a field "userAuthenticationRequired", and using a Builder to set that field as part of building an encryptor. This allowed me to test authentication by passing in an Encryptor with userAuthenticationRequired when running the app, and without that field as false when testing the app.
Related
i was trying to implement the biometric authentication in android studio using either biometric or lock screen credentials and the problem is, the cipher.dofinal() method needs an input , that is given as this in the documentation :
val encryptedInfo: ByteArray = cipher.doFinal( /*input*/ plaintext-string.toByteArray(Charset.defaultCharset())).
I want to know how do i actually use the plaintext-string in the code ?
The plaintext-string is giving me an error. On hovering it says create abstract property plaintext.
As we know, we have an api in KeyguardManager for authenticatng the user through his device lock. The api is : confirmDeviceCredentialIntent.
The doc for this api says :
Get an intent to prompt the user to confirm credentials (pin, pattern or password) for the current user of the device. The caller is expected to launch this activity using startActivityForResult(Intent, int) and check for RESULT_OK if the user successfully completes the challenge.
Now, my problem is, I want to invoke this flow in a non-activity context. I am using a kv store in my app whose contents would be encrypted by the key that I am storing in android keystore. So when I want to get any value fro that store, I first need to authenticate user so that I get my key and decrypt the content before returning.
Second thing is, I, as a consumer of that kv store, don't want to be aware about how the encryption of the store is done and therefore I shouldn't invoke confirm credentials myself. I just want my value from the store and it's store's (which is non-ui component) responsibility to invoke the authentication flow if it's required.
So mostly, I'd be using the global application context. And this context doesn't provide startActivityForResult api.
Is there any other way by which I can get result of confirm credentials action from user?
I ended up using a Dummy Activity. This activity itself is launched by application context and then it handles invoking confirmCredentials intent for result.
In our Android app we are able to get authentication tokens without any user interaction (for the purpose of knowing that an api call was received from our app, not for the purpose of getting any user info)
We use:
GoogleAuthUtil.getToken(context, anyAccount, "audience:server:client_id:" + MY_CLIENT_ID);
How can we do something similar to authenticate api-calls from a chrome extension?
UPDATE:
This is how we get authentication w/o user interaction on Android:
http://android-developers.blogspot.co.il/2013/01/verifying-back-end-calls-from-android.html
Fortunately when calling getAuthToken, you can pass a flag ('interactive': true) or ('interactive': false)
('interactive': true)
If you invoke the API in interactive mode, the user is shown a sign in and/or approval UI when necessary, as shown in the screenshot below:
('interactive': false)
If you invoke the API in silent mode, the API will only return a token if it's possible to produce one without showing any UI. This is useful in cases when an app is doing the flow at app startup, for example, or in general in cases where there is no user gesture involved.
NOTE
The best practice we suggest is to use silent mode when there is no user gesture involved and use interactive mode if there is a user gesture (for example, the user clicked the Sign In button in your app). Note that we do not enforce any gesture requirement.
I want to authenticate my Android app using pin/password set for device security/lock screen. Is there any way to achieve this? May be, app will launch some system Activity, which will prompt for password. The system Activity should return success/failure.
Began from Android 5.0, you can use KeyguardManager.createConfirmDeviceCredentialIntent()
This method will create an Intent, which can be used to start system authentication (pin / pattern / password).
For more information, refer doc and Confirm Credential sample.
App Start
(Is password already created?) <--check in sharedPreferences(This is a good way to store info)
Yes No
Prompt for pass Prompt for creation
Login if correct Login
To do this you can use SharedPreferences, once you have stored a key you can retrieve it on app start up to decide what to do.
I was trying to use Android Password expiration feature using
DeviceAdmin. When I call setPasswordExpirationTimeout() API , it only
sends a notification and doesn't actually force the user to change the
password. It only sends a notification after timeout:
V/DevicePolicyManagerService( 662): Sending password expiration
notifications for action
com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION
You have to get the callback in DeviceAdminReceiver in
onPasswordExpired() to force user to change password.
Any specific reason it's been implemented this way (or is it just to
give flexibility to the programmer)?
The only option I could see is starting activity with intent ACTION_SET_NEW_PASSWORD in the callback in DeviceAdminReceiver which the user can overrule by simply pressing 'Cancel' button.
How to 100% enforce the to change password ?
Have you tried looking at the DeviceAdminSample (source code)? The Android SDK comes with all the samples so you can easily add the ApiDemos as an Eclipse project and run it in the simulator.
I originally thought you could call the resetPassword method in the DevicePolicyManager, but you would need the user to have given you their new password to do that, which I assume you don't want to do!