confirmDeveiceCredentialIntent from non-activity/application context - android

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.

Related

Automatically testing an Android function that needs user authentication

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.

Chrome extension: Authenticate with backend without user interaction

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.

System authentication in Android app

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.

Google Play Game Services - not signed in on next activity

In my application, i have in game helper(i want log in on button click):
// Whether to automatically try to sign in on onStart(). We only set this
// to true when the sign-in process fails or the user explicitly signs out.
// We set it back to false when the user initiates the sign in process.
boolean mConnectOnStart = false;
In my MainActivity (extends BaseGameActivity), after login button click i call:
beginUserInitiatedSignIn();
Of course now isSignedIn() returns true.
But when I go to next Activity (aslo extends BaseGameActivity):
isSignedIn() return false.
I can of course call beginUserInitiatedSignIn() on my next Activity, but i don' t want it.
In my app user can be logged in, but not have to. So if user not logged in at my mainActivity i don' t want show login form on next activity.
Edit: For this moment my solution is to create static variable and set it when i leave my main activity for ture if isSignedIn() and call beginUserInitiatedSignIn() on next activity only when this variable is true. Is it any better, automatic solution ?
There's two types of sign in:
The user initiated sign in which shows the Google Play Games logo and requires the user to approve access, etc.
Silent sign in (which BaseGameActivity does in its onStart call) - this automatically attempts to sign in and, if the user has already signed in, does the same callback as if you had gone through the user initiated sign in flow.
Therefore you do need to wait for the sign in callback before attempting any Google Play Games related calls in each and every activity.
Note that recently (4 days ago on Feb 18, 2014), the BaseGameUtils library for Android was updated to use the new Google Api Client model, which allows you to do read calls before being signed in (where they will automatically wait until sign in before attempting to process). As the Google Api Client gives a number of other benefits (such as improved sign in reliability), you should update to the latest BaseGameUtils if you haven't already.

Facebook SSO returns when app is killed

I use facebook for android sdk for SSO.
My activity calls fb.authorize() function to do OAuth. In this function I give a reference to the DialogListener object that is responsible to take proper actions depending on OAuth results. It is possible that the OS has killed the activity by the time user returns from FB App and the DialogListener Object is lost. In that case there's no way to get the AccessTokens which we were supposed to get in DialogListener.
How to handle this situation?
You can call:
mFB.getAccessToken()
But you can store the session in SharedPreferences to reuse it locally. Tokens will expire and will be requested and stored when needed again.
https://github.com/facebook/facebook-android-sdk/blob/master/examples/simple/src/com/facebook/android/SessionStore.java
I am answering this myself.
Facebook app after doing OAuth returns results in an intent data which we get in onActivityResult(); It is required to call mFB.authorizeCallback() in onActivityResult.
If you look into the source of this function, you will know how to extract it from the intent data. And doing that you can get access tokens in onActivityResult.
Here's the link to the source
https://github.com/facebook/facebook-android-sdk/blob/master/facebook/src/com/facebook/android/Facebook.java#L417

Categories

Resources