Flutter Android oAuth with user certificate caching - android

Current State:
I am implementing oAuth Authentication for a flutter app running android and iOS.
For iOS my Authentication process works perfectly. I want to get the user prompted for his user certificate every login. Therefore I pass the parameter prompt=login when getting the authCode.
On Android the certificate is getting cached in the browser, so the authentication is triggered without selecting a certificate again. Even when sending the prompt=login parameter.
I have used a couple of libraries.
flutter_appauth
flutter inappwebview
oauth2
The main problem is that when I use a webview the browser doesnt bring up the cert picker.
When I use e.g. custom chrome tab like in appauth there is no possibility to clear the custom tabs cache or chromes cache on logout.
When I use system browser like in oauth2 library I have also no control over the cache.
I have also tried implementing java code to access the cookiemanager to clear cache, but this also only accesses webviews.
I have experienced when I kill the browser app after logout the cache is getting deleted and I get prompted again.
Any solution on how I can clear the cache on custom chrome tabs, system browser or implement the webview that it brings up the cert picker?

Related

InternalServerError when completing OAuth authentication flow after returning from action button

I’ve built a plugin for Banno Mobile & Online and I’ve got the OAuth authentication working as described in the documentation. It follows the same structure as the simple plugin example, so it automatically initializes the authentication process when the page is reached without an auth code or state. When it is reached with an auth code and state in the url, it uses them (along with the code verifier stored server-side) to retrieve the identity token. The plugin also has a primary action button that links to an information page at a completely different address.
The plugin is successfully completing authentication and retrieving an identity token in all cases except for one. In the Android version of the Banno Mobile platform, when the user clicks on the action button, it opens the link in a new window as expected – but when the user closes the window and returns to the application, the plugin is reloaded with the previously used auth code in the url. As the plugin is designed, it tries to use the auth code to retrieve the identity token, which fails since it was previously used.
Is there something besides the url that my plugin should be looking at to determine how to handle the authentication flow? This issue is not happening anywhere in the iOS or browser versions of the Banno platform, so this appears to be the only use case where the plugin wouldn’t be expected to fully reinitialize its authentication.
In a native mobile app, the plugins are rendered in a webview. As the app changes state, those webviews can be re-initialized. This will cause the webview to "reload" the page with the full URL.
Of particular importance is that your plugin is designed to handle these reloads gracefully. One of the common issues is leaving an OAuth2 code in the URL which will cause problems. OAuth2 codes are only able to be exchanged one time for an access token. If the page reloads with the code still present in the url, your app is likely to attempt to re-exchange that already used code and an error will occur.

SAML authentication on Android mobile app

I'm trying to integrate my android mobile app with SAML authentication service.
I created a webview and call the provider url.
My webview is redirected to the auth form and I fill it with user and password but after that my webview is redirected to a page showing me the following error message:
"Unable to process request due to missing initial state. This may happen if browser sessionStorage is inaccessible or accidentally cleared."
I can't understand how to solve the issue and complete the authentication using the webviews.
I can't find a good example of this authentication using webviews or chrome custom tabs.
You need to enable session storage on the Android Mobile App.
See here on how to enable it: https://www.tutorialspoint.com/how-to-enable-web-view-session-storage-in-android

User authentication is not persisted on WebView

I'm creating an Android app that has a WebView which accesses my website hosted using Firebase Hosting.
If I sign into the website using email/password credentials and then refresh or navigate to another page, Firebase loses my login information.
I tried to force Firebase to keep my credentials using firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL) but it throws this error in the WebView console:
Uncaught Error: The current environment does not support the specified persistence type.
As a side note, I tried logging in on other services, such as YouTube and Google to see if it was a browser cache problem, but the session was persisted normally, even after I refreshed the page, navigated or reopened the Android app.
I also tested the Android app using the emulator (running Android 8.0) and a phone (Android 6.0).
Does somebody know what's going on here?
You need to enable DOM storage in your webview as Firebase Auth depends on web storage (localStorage/indexedDB) to store the Auth state.
webview.getSettings().setDomStorageEnabled(true);

OAuth 2.0, Android and cookies

What is the point of using OAuth 2.0 client-side authorization in Android if built-in WebView browser doesn't have access to cookies of default user browser? I mean, if I open some oauth-url (e.g. http://blablabla.com/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=token) in WebView - the user will anyway be prompted to enter his credentials to sign in to "blablabla.com" social network. Because even if he is already signed in with some of his browsers (Opera or Dolphin, or default browser), the WebView browser doesn't know anything about corresponding cookies.
EDIT:
I'll try to make it a bit clearer.
The main goal is to simplify sign-in procedure in my application. I'd like to implement such mechanism that we can see on many web-sites: "Login with... Facebook/Google/Twitter/whatever". And in desktop browser that approach works perfectly, because the end-user is already signed in to aimed service WITHIN THIS BROWSER. So basically to sign-in in to my site all he needs is:
Press button "Sign in with..."
On redirected window/popup press
"Approve/Confirm".
Get redirected back, already being signed-in.
The main benefit is that user doesn't need to enter his email/name/whatever - I've already extracted it from his social-network account.
And I'm wondering how to get same effect on Android. The problem is that, as I can see, we can't let user avoid entering password, because the application (WebView) never knows if he is signed-in to some outer service or not. That's why user anyway will be prompted to enter some of his details and all of OAuth benefits become annihilated.
The workaround depends on what you are trying to do. It's not clear to me, looking at your question again, because you do not explain your use case. Instead you are indirectly asking for something that looks very broad as if you want to maintain an Android system-wide login state that spans over multiple applications using shared cookies.
Due to security reasons that is neither good nor wanted. A rogue app could do whatever it wants to do with existing access tokens requested by other apps or just temper with or read existing cookies created and maintained in other apps.
Assuming you are trying to authorize your own app access to a web service using OAuth 2.0 by letting the user log in with a WebView, you need to implement your own WebViewClient, override its onPageStarted or onPageFinished method and check whether the URL argument matches your redirect URL.
If there is a match you need to extract the access token from the URL string. If there is also a refresh token available, then extract that one, too.
(This however only works for a certain type of OAuth flow, which adds the access token to the redirect URL.)
Now you have at least an access token available. Store that token in the private preferences of your application and use it in your service requests until you get a 401 not authorized error message back from the service. At that point you can use the refresh token if available to request a new access token or you have to show the login WebView again.
If you are trying to access a Google service from your app you may find the article Getting started with the Tasks API and OAuth 2.0 useful.
Have you considered launching the browser externally (non-embedded)?
That will benefit from existing cookies and also give users the trusted UI they are most comfortable with when entering credentials to these services. (in other words - users see the SSL lock, the correct URL in the address bar, etc.)

Performing authorized (through facebook) REST requests to my node.js server on a PhoneGap app

Since this issue is about three technologies I'd like to quickly introduce each of them:
node.js: javascript on the server side (consider it my webserver)
PhoneGap: framework that allows me to write Android applications in HTML/Javascript/CSS.
facebook authentication: using everyauth to let my users login with their facebook account
The objective: I need my PhoneGap application to communicate with my server using a REST based protocol. Many of these requests may only be made when the user has logged in to my server, using their Facebook account. Thus, the user needs to login and then go to the logged in state of the PhoneGap application.
The issue: When I setup everyauth for facebook I basically have an URL, like domain.com/auth/facebook which will redirect to Facebook's login "popup". When the user then accepts the login, the server will know, and so far everything is good. The problem is that
the user now has to be redirected to some external URL, while he should simply get back to the PhoneGap application (in a logged-in state)
The PhoneGap app does not retrieve the authentication token, or whether authentication was successful or not, because the login process is done in the external URL domain.com/auth/facebook while the PhoneGap application's HTML is stored on and run from the phone itself
Cause of the issue: the reason this issue appears while it does not for a normal web application, is that the PhoneGap application's HTML files are stored and run from the phone itself while authentication goes through domain.com/auth/facebook, which is considered to be a different domain.
Suggested approach #1: a PhoneGap user has recommended me to use this Android-Facebook plugin for PhoneGap. The issue here is that the server does not act as an authentication middle-man. Thus, the user would have to inform the server of their authentication token instead of the normal approach where the server informs the user of a successful authentication procedure and the corresponding tokens. This seems like a severe vulnerability.
How should I tackle this issue?
With the ChildBrowser plug-in, a PhoneGap app can monitor location changes from the authentication site.
We used this approach to integrate a PhoneGap app with a node.js openid module
I have implemented one solution for Twitter using jsOauth and ChildBrowser (tut./src here) for a PhoneGap / Android app. I know this doesn't include custom registration with a nodejs server; it allows access to Twitter REST only. AFAIK this is the only way to do it currently, that is, have the child browser check each new location to see if it's your app's return-to url, then intervene (close browser window) and go to your own app.
With jsOauth library, the auth token key/secret are stored for you and sent with every request.
Re: security - No expertise here, but discussions conclude this kind of data on one's personal phone are no more at risk than everything else on the phone.
Tut. using PhoneGap / Android Facebook plugin in next on my list. Thanks for link to everyauth!

Categories

Resources