I'm using SFSfariViewController for OAuth process. Using this I'm getting a quite well response. Whenever redirecting happens, it's opening my app. But when the request fails, I'm not able to show any alert to the user to indicate authentication failed. At this point, I can't customize SFSafariViewController as it won't allow customizations. So that's why I want to move to WKWebview which allows customization.
Even though WKWebView allows customization, From this article it's saying that Web views are not good to use for OAuth process and using SFSafariViewController is the best in this situation.
My Question:
Which one has to use WKWebview? or SFSafariViewController?
If so, Why?
Thanks in advance!
SFSafariViewController.
It's better for:
user security
credentials protected from app developer
ease of use for users
use of stored Safari credentials
Safari shared cookies/authentication maintain login across apps
I think it's fairly safe to say Apple will start enforcing the use of SFSafariViewController for the OAuth flow for the sake of customer privacy and security.
Related
I'm not sure there is a "proper" way, but before I just bodge together my own incompatible implementation, perhaps there's something in all the standards that can fit my need?
Here's the situation: Apple has declared that apps on their phones MUST include all standard functionality inside themselves. No more iframes with web content! If you need to show stuff from web, open the system browser (Safari)! Unfortunately we need to display stuff from web, so here we go...
Now, the app requires authentication which the user has done previously. We store whatever tokens we need. When the time comes to open the browser, we don't want to force the user to re-authenticate. We need to somehow pass the access credentials to the browser, and preferably do this securely. Furthermore, the webpage in the browser will need a token obtained from our OpenID Connect server.
Unfortunately, the only point of communication between the app and the browser is the URL, so everything that we give will be there, in plain sight. I know that OAuth was pretty worried about this, so much so that they made it impossible to intercept authentication with just the stuff visible on the screen and instead using things like single-use intermediary codes, backchannels and PKCE.
Unfortunately I cannot see any way to use the default flows "out of the box" to achieve what I need. I can think of modifications to those flows that would do it, but I'm not a security expert so I'd rather go with something standard which is vetted by experts.
SCENARIO
It's a good question since many companies want to show existing web content in a secured manner within a mobile app, and to avoid an extra login.
WEB + MOBILE INTEGRATED SOLUTION VIA DISCONNECTED BROWSER?
Ideally what you want to do is pass the mobile app's JWT to the external web content in an HTTP header. iOS APIs such as openURL may not support this however.
You may have to pass a JWT in a query string, in which case I would try to follow a signed request model, though it is not trivial. I have used SalesForce signed requests though not implemented a full solution myself.
Mobile app calls an API method at POST /api/encrypt-token
API returns an encrypted payload that includes the JWT
Mobile app opens a web page at https://mywebapp?token=0a78904cwdu
Web UI calls POST /api/decrypt-token to get the JWT
Web UI stores the token in memory and uses it to call the API
You will want to prevent raw tokens being written to web server logs.
I believe the recommendation for this type pf solution is to use a one time key, as described in the above link. And of course the web session will have some limitations such as silent token renewal not working.
WEB + MOBILE INTEGRATED SOLUTION VIA WKWEBVIEW
In the past I've managed secured web content in a mobile app by making the Web UI get access tokens from the mobile app. This enables an integrated UX and you can use a 'standard as possible' OAuth solution.
When the Web UI runs within a mobile app's web views it no longer does its own OAuth handling and instead calls the mobile app to get tokens and trigger logins
This means there is a single login across web and mobile views, and the Web View gets all the benefits of mobile user experience, such as secure storage of tokens
The Web UI is no longer impacted by things like the web view aggressively dropping cookies
VALID USE OF WEB VIEWS?
Web views are probably not a good long term solution in most cases. I know that Apple are likely to reject apps in 2020 if they use any of these behaviours:
Use of UIWebView - the Cordova default - you need to update to WKWebView
Delivering an app that is solely a repackaged web site with no mobile views
Displaying web content of a dubious nature (ads etc)
I suspect that use of WKWebView used responsibly and justifiably would be accepted. I could be wrong though, so please don't take my word for it.
ONLINE SAMPLES
I will be documenting some stuff about mobile / web integration on my OAuth blog, including code samples.
Our user experience team does not like the consent popup every time login page is opened. Also, we are looking to customize the look of the browser window presented when OAuth is implemented using ASWebAuthenticationSession/SFAuthenticationSession.
For the reasons above, I am thinking to change the implementation and use SFSafariViewController directly for Authentication.
Although I did not find any reference for this, but I am worried if using SFSafariViewController for OAuth would give problem in Appstore submission as Apple has already provided a way for it in form of ASWebAuthenticationSession/SFAuthenticationSession? Does anyone has a view on it?
Since iOS 11 SFSafariViewController no longer shares cookies so I'm afraid that's not possible.
I am using Auth0 for authentication in my app, I've put the login button on the app's home screen , pressing the login button moves the user away from our app and into another location(Auth0 site), and then it takes us back after successful authentication. Is there any way of doing this with Auth0 that you stay within the app itself? That is, the user would not know that the app is using Auth0.
Yes, assuming this is a web app you can use an Embedded Login by placing the Auth0 Lock widget on your page. There are some security hoops you have to jump through if you do that (enable cross-origin authentication, use Custom Domain Names or assume your users have 3rd party cookies enabled, etc.). There's a good pro/con explanation of the two approaches here:
https://auth0.com/docs/guides/login/universal-vs-embedded
Also, there may be some ways to roll your own UI and use the Auth0 API to authenticate. The down side there is you may be introducing some security holes that Auth0 presumably wouldn't (since they're the security experts).
I assume this app is a web application.
In that case you can use a custom domain. You can specify something like login.example.com. Where example.com is your app domain. Please note that custom domain feature is not available for free plan.
I'm not sure if it's possible. I'm currently developing an app the stores password (like a password manager). One of its features is to allow user to make an auto login to a web browser of that device. I was able to make it work using UIWebView and WKWebView but can't find a way to make it work using SFSafariViewController. I read few documentations and blogs about it and even read the SFSafariViewController.h but there's no clue in there that can lead me to the function that I wanted. I want to know how to do a "evaluateJavaScript"-a-like function in SFSafariViewController or if its not possible, do you guys have other suggestions on how to achieve this?
Note: I'm using Objective-C.
Thanks in advance!
Happy coding!
SFSafariViewControllers are sandboxed. As they are essentially Safari, and have access to cookies. It would be a security risk to allow any app to access these.
However, if the web-service you want the user to sign in to is yours, you can setup a API and a custom URL scheme.
Follow this documentation.
If you are trying to store passwords etc from sites you don't maintain then unfortunately, this is not possible using the SFSafariViewController.
Hope this helps,
Liam
I have an iOS application which allows the user to use Apple's built in Accounts/Social frameworks to login via Facebook.
One question I have is, is there a way to pass user auth cookie from ACAccountStore to a UIWebView?
This will mean that, if a user clicks on a link and the built in web view page is shown, they will be able to comment/like/etc without having to login in the web view too.
Thanks,
Dan
I think it won't be possible if you don't control the service you want to be authenticated with in said webviews.
Injecting arbitrary cookies into a UIWebView is possible, as described e.g. here: Is it possible to set a cookie manually using sharedHTTPCookieStorage for a UIWebView?.
Cached auth tokens can be retrieved from ACAccountCredential. But OAuth tokens are not session-authenticating cookies.
Facebook does that. Whenever a webview is opened in their iOS client, the user will be automatically authenticated with Facebook in that webview. But they have control over their own service, so they created a mechanism for their iOS client to request session-authenticating cookies (that they then inject into webviews).
In general, though, being a 3rd party developer, you won't be able to reproduce that behavior. Unless of course given service has such mechanism for their own needs and you do some reverse-engineering.