How to perform mTLS in a flutter or iOS application - ios

The bounty expires in 4 days. Answers to this question are eligible for a +250 reputation bounty.
Jugal Thakkar wants to draw more attention to this question.
I have an enterprise Flutter application that needs to launch the login page for the user's Identity Provider (IdP) inside a webview within the app. The IdP supports certificate-based authentication using a certificate present on the user's device (through MDM) to authenticate the user without needing to provide any credentials.
When launching a safari browser to launch this page, it works fine. Safari prompts the user to select a certificate the first time from the ones available and Safari sends it to the server and page successfully proceeds to present the protected resource.
Another requirement is that we need to open the IdP page using a specific user-agent string so that their firewall can be configured to only allow selected apps and not any random Safari page.
Unfortunately, the Safari In-App Browser does not allow overriding user-agent. While using an in-app web view using https://pub.dev/packages/flutter_inappwebview or https://pub.dev/packages/webview_flutter we are unable to get the certificate prompt like the one we see in safari and the communication fails with the following SSL error, with code -1200
An SSL error has occurred and a secure connection to the server cannot be made
When using InAppWebView from https://pub.dev/packages/flutter_inappwebview and accessing the protected site, the onReceivedClientCertRequest handler gets invoked, but I am not sure how to pass the device certificate back in the response. The ClientCertResponse expects a path to the certificate, what should this be?
Is there a way to retrieve the appropriate certificate from the OS's secure storage (keychain?) and send it to the web page? Either Flutter or native iOS code is ok. We are only focusing on iOS for this use case.

Related

Oauth2.1 protocol moves out of password mode, how to log in mobile app for the first time

I am using spring authorization server
This project has removed support for password mode
How to authenticate when an android app user logs in for the first time???
Can you give some examples Android of REST api???

Safari cannot open the page because the address is invalid after successful uber oauth

I'm linking to the uber api authentication endpoints (/authorize and /token) via iOS and after a successful login, it returns "Safari cannot open the page because the address is invalid". I've narrowed this down to an iOS specific problem because the same react-native configuration works for Android.
I've tried a number of solutions.
Clear safari browsing history, web data, iPhone update, etc. Nothing has worked.
I believe URL Schemes under URL Types in info.plist has a pay here, but I'm struggling to wrap my head around what I need to put there.
Any thoughts?
Upon successful authentication, uber should return an access token for the user.

Cookies not being set on iOS using identityserver

I have a mobile app that is using ODIC authorization code flow. Our server implementation is using Identity Server 4.
The mobile app opens a browser window and I can login to a 3rd party provider just fine, it then redirects to /signin-adfs on our identity server, which sets some idsrv.external cookies and returns a 302 to /External/Callback. The browser redirects to /External/Callback but doesn't send any of the idsrv.external cookies with it so Identity Server throws an exception because the result from HttpContext.AuthenticateAsync is not successful.
I'm kind of stuck at this point because I'm not a mobile developer. I deployed and have customized Identity Server slightly in other areas but not this part of the code.
I believe the mobile app is opening a Safari session to do the auth. Is this an issue with the cookies that the browser doesn't like (domain, path, https, secure)? or something else? The cookie size is chunked to 4KB a piece. I'm not sure what could be causing this issue.
To make things even weirder... if the browser is refreshed (/External/Callback) then the request works and the iOS app gets the code and can make the follow up request to get the token.
Was digging through the IS4 source and saw a link to this issue on github. Looks like it was fixed in source but hasn't been released yet. There are some workarounds in the github issue if you need it sooner than the release. The problem is specific to iOS 12.

HTTP authentication in iOS 7 web apps doesn't respond

My organization had a web app that worked perfectly in iOS 6. You'd visit the website, the website would tell you to add the page to your homescreen, and boom, a nice HTML5 web app was added to the home screen.
Because we're processing sensitive data, the web app used HTTP authentication (via the native WebKit auth dialog) to authenticate user/passes. It worked without a hitch until iOS 7. Now when someone tries to summon the HTTP auth dialog, nothing happens. It's clearly trying to load something, as the spinner in the status bar appears, but no dialog ever pops up, essentially breaking the "app."
Has anyone else run into this? Is this something you'd consider to be a bug on Apple's end? Any workaround?
My company ran into this last fall, starting with iOS 6, and what we have been able to ascertain is that it is a genuine Apple Safari bug as part of its security "enhancements". No real explanation from them for rationale, but here is what we see in the debug and packet sniffers.
In normal operation, the Safari browser will request a page (or an object in the page) from the server on a GET. If that asset is protected with an Access Control List, in our case Apache Basic Auth, and it is the first request on that host in the session, the server will respond with a 401 HTTP response header indicating to the client (the browser) that it needs to request again, this time adding a basic auth header that has authorization credentials. The browser then presents a login dialog to the user, where they can enter user and pass credentials, and either submit or cancel the request. On submit, the client re-requests with those credentials in the auth header.
Assuming the credentials are accepted on the second GET request, the proper asset will be returned on the response, and the document in the browser will proceed with loading the rest of the page (assuming it was a page you requested). If you have embedded assets that reside on a different host, and that host requires authentication for that asset, the process is repeated as the page loads.
Here's where it gets broken. If you embed calls to objects from more than 2 hosts total on the same page, which require basic authentication, the 3rd authentication prompt on that page is suppressed, so the browser spins forever waiting for you to enter credentials on a prompt that you never see. Your Safari browser is now hung up on that stalled authentication prompt, on this and any other tab, even on a reload, and you will not get another prompt unless and until you hard-close your browser or restart your device.
This does not affect Chrome, just Safari, and it is both on an iPhone and an iPad with iOS 6 or later. I have the latest iOS version as of this writing (7.0.6), and the problem is still there.
We had a workaround last year, where we would create an internal page that had an array of each of the embedded hosts, which we would then loop through with an iframe embedding a call to the favicon.ico at that host's location. That worked until recently, where now, perhaps because of the iOS 7 feature of freezing background tabs, the auth prompts are frozen up again.
Here was the JavaScript sample:
hosts=["store","profile","www","secure-store","images","m","modules"];
devhost=location.hostname;
var i=0;
while (hosts[i])
{
newhost=devhost.replace('store.mydomain',hosts[i]+'.mydomain');
document.write("<iframe Xhidden seamless=seamless width=0 height=0 src=http://"+newhost+"/favicon.ico><img height='16' width='20' alt='NOT' title='NOT AUTHENTICATED' src=http://"+newhost+"/favicon.ico> Authenticated on "+newhost+"</a></br></iframe>");
document.write("<img height='16' width='20' alt='NOT' title='NOT AUTHENTICATED' src="+(newhost.indexOf('secure')>0?'https://':'http://')+newhost+"/favicon.ico> Authenticated on "+newhost+"</a></br>");
i++;
}
The second set in the document.write would give a visual indication of which hosts have been authenticated, as their favicon is now displayed. It also lets you know which host might be stalled, as its icon is missing.
Since this workaround stopped working on iOS 7, the only cumbersome solution we have is to pre-open a separate tab for each of the favicons (directly in the URL), enter the auth, go back, go to the next one in the list, and repeat until you have cached all of the auth credentials for all of the hosts used on the page. At that point, you can load the original page since your creds are now cached. Cruddy, and completely unreasonable for an end consumer, but is what we need to do for testing sites that are behind a public CDN, as we need to protect assets on that development site with an ACL.
As of today, we are still figuring out a better workaround. Not an issue on Android, Windows, or any other iOS.
Sure worked better when Jobs was alive.
Hope some of this helps.
I have the exact same problem. Basic authentication worked with previous iOS versions but not with iOS 7 in combination with web apps added to the home screen. I think this may be related to the dialog problem described here.
Standard dialogs are not working at all, such as alert, confirm or prompt.
The login prompt that is shown to authenticate the user is probably blocked (does not work or is not visible) and that is why the web app does not pass through the authentication phase.
I suppose Apple will have to fix this bug in a future release.
Edit: After upgrading to iOS 7.0.3 basic authentication suddenly started to work again also in home screen web app mode. Login prompt is displayed and everything works as expected.

Wifi Authentication [duplicate]

When I go to a place with a WiFi hotspot (such as Panera Bread) and connect with my iPhone, the hotspot login page appears as a popup. That is, no matter what app I'm running or what web page I'm on, the login page scrolls up from the bottom, asks for my login credentials, and then disappears.
But at some other hotspots, I don't get the login page until I go to Safari and try to load a web page.
What is the iPhone looking for that causes it to pop up the login page at some hotspots and not others? Is there a special HTML meta tag? Or is it related to the way the redirect is implemented?
I managed to find out the correct term for this authentication type: "Captive portal". Punching in Captive Portal iPhone into Google turned out a few technical details from these pages: one, two, three.
To implement a Wi-Fi popup login page:
DNS request for www.apple.com must not fail
HTTP request for http://www.apple.com/library/test/success.html with special user agent CaptiveNetworkSupport/1.0 wispr must not return Success.
I have not tested this, but it sounds about right.
Comments below mention that iOS 7 behaves differently and may query more than one server. I have not tested this. So easiest would be to simply redirect all HTTP communication to your login page, and block all non-HTTP communication.
Microsoft's captive portal detection uses something similar to pre-iOS7 behavior: its Network Connectivity Status Indicator attempts to contact http://www.msftncsi.com. Windows 8 and 8.1 also include support for WISPr.
Android's captive portal detection, as of AOSP 4.0.1, tries to contact http://clients3.google.com/generate_204 or http://www.google.com/blank.html.
So to be as universal as possible, you'll want to simply block all communication except for authentication, and include WISPr support on the login page.
I'd say "go with a proper authentication on your network" -- something universal such as PEAP+MSCHAPv2 -- but Windows makes it very painful for your users to set it up. I don't know who thought that "Use your Windows authentication details" makes a sane default on machines that are not part of a corporate domain network, or even why "Check certificate validity" is a sane default, as most networks will not consider getting a proper certificate a priority.
iOS 6 has apparently fixed WPA2 EAP as it's suddenly popping the login window now.
Our companies public WiFi requires accepting the terms regarding monitoring, etc. I always had to manually open Safari on iPhone or iPad and navigate somewhere, it redirects to an internal acceptance page and when you clicked the Accept button it would go where you originally were headed.
Today, I updated to iOS 6 and was plesantly surprised to see the Login window slide up from the bottom and allow me to click the Accept button without even opening Safari.
I suspect that when the login page pops up the Wi-Fi is using EAP. This is a Wi-Fi protocol for authentication. In the case where you need to go to a web page then the authentication will be a custom access implemented by a server (i.e. at a higher level
than EAP).

Resources