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.
Related
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.
I'm having a problem with the lite version of messenger (android only)
This version of the application does not support bot messages with templates or buttons (including the get_started button)
In my case this is an example:
I could not find a parameter in the webhooks to provide the user's platform.
So I have to ask the user: do you use the lite version?
And then set a different flow.
But this means that I must also give the possibility to disable the lite mode when browsing from the web or from the non-lite application (to guarantee a better user experience)
Does Facebook Messenger Bot provide information about the channel where the message was originated ?
This information is not provided via webhook, currently. The closest you can get is detecting user agent in the webview.
A not ideal but doable option would be to have something like a 'Switch to Lite' button in the persistent menu
One way to identify where message event originates from is to use the payloads. You can specify a unique payload when setting up your bot and check what you receive to react on. get_started, persistent_menu, quick_replies have a payload field that you can set.
{
"get_started":{
"payload":"<GET_STARTED_PAYLOAD>"
}
}
For example, user is navigating to google.com in WebView.
Is it possible to authorize him there via Google Account Picker (something like described here https://developers.google.com/android/guides/http-auth) to simplify authorization instead of manually logging in via web form?
Android Web browsers (for example, Google Chrome) are authorizing user via this method).
Part I: Using the Google Plus Services API
If I understand your question correctly, you may be able to achieve what you are trying to do using the Google Plus Services API.
You create your GoogleSignInOptions and then create your GoogleApiClient using these sign-in options. From there, you use the Auth.GoogleSignInApi.getSignInIntent with your GoogleApiClient as the parameter.
This intent should launch a SignInIntent that presents the Google account picker (that will include accounts that have been accessed on the device previously, and the ability to add another account).
Once you get back the GoogleSignInResult, you can verify that the user was authenticated and then create the authentication flow as you would otherwise.
Even included in the Android SDK is the Google SignInButton, which you can use right in your layout instead of having to create a custom button for the sign-in.
Part II: Using WebViewClient
Now, if you are trying to use a WebView to authenticate them, your best bet is to extend the WebViewClient class.
Things you will need: clientId, clientSecret, and clientScope (all of these details will be given for you when you create your application in the Google Developer Console)
First things first, your URL to authorize will probably be as follows: https://accounts.google.com/o/oauth2/auth?response_type=code&clientId={your client id}&state={SOMESTATEINFO}&access_type=offline (access type if you want offline access). This should be the initial URL of your WebView
Next, you will want to modify your extended WebViewClient class. What you will want to do is override the shouldOverrideUrlLoading(WebView webView, String url) method to listen for your redirectURL. Probably the easiest thing to do is to use url.startsWith(<your redirect URL>) to detect this. You can then parse the response. If your response contains error, then it means something went wrong. Otherwise, you should get back two fields in the URL: code and state. If you do not get error back, then return true for shouldOverrideUrlLoading.
Once you get your code, you can create a new GoogleAuthorizationCodeFlow, using your client, scopes, and secrets.
Once you have your flow, you will need a GoogleTokenResponse, which you will be able to get using the code obtained above for your authorization code, using GoogleTokenResponse response = flow.newTokenResponse(<code>).setRedirectUri(<redirectUri>).execute().
Once you have done this, and you have your response, you can get your Credential using flow.createAndStoreCredential(response, null).
And voila, using this Credential, you can authenticate your calls.
Caveats I have not been able to get the WebView to recognize accounts that have been signed into on other web browsers, so the account picker may only show the accounts that have been signed into on the app-specific WebView.
tl;dr It is possible to do this with a WebView and WebViewClient, but it's messy and a little bit more roundabout than using the Google Plus Services API.
This example better illustrates the authorization flow/credential stuff once you get the authorization code and such.
And here's some documentation on the WebViewClient that may be useful as well.
Hope this helps point you in the right direction!
I am looking for an alternative for captcha to use in our mobile applications. We are writing a mobile application in iOS and Android. The web application is already exist. In the web page we are using captcha to ensure only genuine customers are applying and to prevent denial of service type attacks.
So from mobile app also we need to take care of these. Any body came across the same situation? Is it recommended to use captcha in native mobile apps?
A mechanism to prevent automated traffic must definitely be used. Not doing so means you will allow a way to access your servers which can be automated. Even though you might think it is only available from mobile apps, an attacker code can run anywhere and bring your system to halt.
If your concern is that captchas will be inconvenient to mobile users, try google Recaptcha. Where usually its a click of checkbox or clicking some images in some cases where google is not able to determine based on the checkbox.
https://www.google.com/recaptcha/intro/index.html
There is a library for android using google recaptcha
https://github.com/ayltai/Android-Lib-reCAPTCHA
Android-Lib-reCAPTCHA
The reCAPTCHA Android Library provides a simple way to show a CAPTCHA as an ImageView in your Android app, helping you stop bots from abusing it. The library wraps the reCAPTCHA API.
Quick Start
First you have to sign up for your API keys.
Installation
repositories {
jcenter()
}
dependencies {
compile 'android.lib.recaptcha:reCAPTCHA:+'
}
The Layout
To show CAPTCHA image, you need to add a <android.lib.recaptcha.ReCaptcha /> element to your layout XML:
android.lib.recaptcha.ReCaptcha
android:id="#+id/recaptcha"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerInside" />
It is important to use android:scaleType="centerInside" to ensure the entire CAPTCHA image can be displayed.
Alternatively, you can create an instance of android.lib.recaptcha.ReCaptcha at runtime:
ReCaptcha reCaptcha = new ReCaptcha(context);
How to show CAPTCHA
In your activity/fragment/view containing android.lib.recaptcha.ReCaptcha, you need display a CAPTCHA image for the user to response:
ReCaptcha reCaptcha = (ReCaptcha)findViewById(R.id.recaptcha);
reCaptcha.showChallengeAsync("your-public-key", onShowChallengeListener);
showChallengeAsync downloads and shows CAPTCHA image asynchronously. It is safe to invoke in UI thread. No exception will be thrown in case of any error by this call. All errors will be treated as unsuccessful in showing CAPTCHA image.
onShowChallengeListener is an instance of ReCaptcha.OnShowChallengeListener, which is called when an attempt to show a CAPTCHA is completed.
The synchronous version of this method is showChallenge.
How to verify user input
To verify user input, pass the input string to ReCaptcha.verifyAnswerAsync (or ReCaptcha.verifyAnswer):
reCaptcha.verifyAnswerAsync("your-private-key", "user-input", onVerifyAnswerListener);
verifyAnswerAsync asynchronously submits the user input string to reCAPTCHA server for verification. It is safe to invoke in UI thread. No exception will be thrown in case of any error by this call. All errors will be treated as verification failure.
onVerifyAnswerListener is an instance of ReCaptcha.OnVerifyAnswerListener, which is called when an attempt to verify the user input is completed.
The synchronous version of this method is verifyAnwser.
Specify a locale
You can force the widget to render in a specific language. Please refer to this page.
reCaptcha.setLanguageCode("fr");
Sample Application
A complete sample application is available at https://github.com/ayltai/Android-Lib-reCAPTCHA/tree/master/reCAPTCHA-Samples.
I am making a Chrome/Android/iOS app using the cca toolchain. I am using the chrome.identity API to get an access_token to interact with Google APIs.
When I set interactive to false (immediate to true) the app is able to get the token without showing the permissions dialog again, but it still shows the account chooser every time on my Android device. This ruins the app experience because every time it is opened the user gets an annoying dialog. How can I make the app remember the chosen account after the first time, like it does with the permissions?
On Android, you can specify accountHint in the details argument of calls to getAuthToken. For example:
var details = { interactive: true, accountHint: 'email#address.com' };
var callback = function(token, account) { ... };
chrome.identity.getAuthToken(details, callback);
This will bypass the account chooser dialog. Note that the callback has account, which can be stored for this purpose.
Unfortunately, this is Android-only; Chrome on desktop doesn't like it when you add extra stuff to details. You'll need to use chrome.runtime.getPlatformInfo to determine what platform you're running on, so that you can create and pass the right details object. On Android, platformInfo.os will be cordova-android.