Single Sign On (Silent Login) using iframe and postMessage while ITP (Safari) - javascript

Short:
I need help in SSO in Safari, I'm using iFrame and postMessage logic which is working fine in Chrome and Firefox (PC, Mac, Android and iOS) but the catch is in Safari. I tried Storage Access APIs and placed those in iFrame's onLoading event to check access. But the localStorage which I was used to store JWT is not persistent in the iFrame. I'm using Angular 11.
Scenario:
I'm developing few applications which uses same auth site for sso, which was working as expected as I said in short description. But when it comes to Intelligent Tracking Prevention enabled browsers as of now Safari, It blocks the iFrame by considering it as 3rd Party Trackers which is very insane since the iFrame's origin (Domain) is same with Sub-domain used in service sites.
I tried to check the access by using storage access API i.e hasStorageAccess() in window onLoad method in the iFrame's script. If has no access, I called requestStorageAccess(). I'm here not using user gesture and using button click from service site because I'm using angular for frontend framework but in order to request using button in iFrame.(Since, The policy specifies to get access works only after user interaction which is another headache for devs)
I need help to overcome this issue and fix the SSO with ITP. Any guidance is useful and I'll keep updated.
Google is working fine with their sso and services such as YouTube and Mail doesn't need login on every visit. Any idea on how they achieved.

The reason could be that Safari has the option "Prevent cross-site tracking" enabled by default and that can interfere with the SSO login and display of an embedded iframe (because it blocks some cookies).
Solution
Disable (uncheck) the option for "Prevent cross-site tracking" in the Safari configuration menu.
Tip: To achieve a better user experience, using Javascript you can detect when a user is using Safari and show him an HTML message explaining that he needs to disable that option in order to continue or use another browser like Chrome or Firefox.

Related

Making an iframe inherit cookies from the parent in Safari

My web app extends a Google Form's functionality by loading it as an iframe, and doing other stuff outside the iframe. If the Google Form requires authentication, Google makes a "Sign In" box appears within the iframe. When a user clicks on the button, a new tab opens, and the user is re-directed to the form in the new tab.
If a user navigates away from my web app, the extra functionality will obviously not work. So, what I am looking for is: to have an authenticated Google Form load as an iframe within my web app.
I can make the user first sign in via Google Sign-In (OAuth) on my web app and then load the iframe. On Chrome and Firefox, the iframe automatically starts with a logged-in session. This is great! But, this solution doesn't work on Safari. Is this related to Safari blocking third-party cookies?
If I want this functionality to work within Safari (and other such browsers), how would I go about doing it? Will I have to use the Storage Access API? If yes, can you broadly tell me how to do it?
For now, I could just ask users to download Firefox/Chrome if they want to use my web app. Most of my users are Chrome users anyway. But, is implementing these privacy measures a part of other browsers' roadmap too? If yes, I may as well try and build a solution that will work in a year or two.
I expect so.
This needs to happen in the iFrame, so Google rather than you need to implement it.
Yes, but not until 2022, so I would hope Google forms will support this by then.

How to implement SSO into safari-app-extension without POPOVER toolbar action

I am trying to make SSO auth in my safari-app-extension. And the only way which I found that is creating WKWebView and getting secured cookies from inside. But there are two problems. The first that this is not really SSO, because WKWebView and safari have separated cookie storage. And the second one I don't need POPOVER tollbar item action (all UI composes inside a page). Is there any way to get a seсured cookie from the safari page? Or at least is there any way to invoke/not-to-invoke popover conditionally?
I didn't have the same problem in old safari extensions because browser cookies were shared with the background part.

Local Storage Cross Domain - Safari disables it by default

The issue:
I have used github project of Ofir Dagan: Storing cross domain local storage.
It implements html5 local storage:
https://github.com/ofirdagan/cross-domain-local-storage
The problem:
Safari doesn't allow third party cookies by default (other browsers allow it).
Safari privacy preferences are:
The default is: "Allow from websites I visit".
I read about these settings:
Always Block - Block all first-party cookies and block all third-party cookies.
Allow from Current Website Only - Allow all first-party cookies and block all third-party cookies.
Allow from Websites I Visit - Allow all first-party cookies and block all third-party cookies unless that third party was a first party at one time (based on current cookies and browsing history).
Always Allow - Allow all first-party cookies and allow all third-party cookies.
Solution I have tried:
Local Storage with an iframe (pixel) - I think it's no longer works on Safari - Is there any workaround to set third party cookie in Iframe for safari?
I think that there is a way to share local storage between first party and third party sites on Safari. (Facebook.com and Booking.com share data between different domains).
I succeeded to achieve it by removing the API and writing it by myself, But I don't want to remove the API and implement it by myself (hope that there is a small fix in order to support Safari):
Iframe.html:
window.addEventListener('cors_event', function(event) {
if(event.event_id === 'my_cors_message'){
if (event.data.options.funcName == "SetItem") {
localStorage.setItem(event.data.options.key, event.data.options.value);
}
else if (event.data.options.funcName == "GetItem") {
return localStorage.getItem(event.data.options.key);
}
}
});
MainPage:
<iframe id="target" src="iframe.html" frameborder="1"></iframe>
<script>
var target = document .getElementById('target');
target.onload = function(){
target.contentWindow.postMessage('set', '*')
}
</script>
So does someone know how can I achieve it by changing some API logic to support Safari?
Any help appreciated!
As noted by the Cross-Storage library documentation:
Notes on Safari 7+ (OSX, iOS)
All cross-domain local storage access is disabled by default with Safari 7+. This is a result of the "Block cookies and other website data" privacy setting being set to "From third parties and advertisers". Any cross-storage client code will not crash, however, it will only have access to a sandboxed, isolated local storage instance. As such, none of the data previously set by other origins will be accessible. If an option, one could fall back to using root cookies for those user agents, or requesting the data from a server-side store.
It seems that the recent updates to the Safari browser (Prevent cross-site tracking) blocks any cookies from being generated when the Matomo domain doesn't match the website it's being loaded from.
This breaks the use of iFrames for Matomo that require cookies to be set (For example the logme feature)
There doesn't seem to be any way to fix this with headers (Eg using CSP or CORS configurations).
current workarounds exist that I've found:
Disable the "Prevent cross-site tracking" setting in the Privacy settings
Redirect the visitor to the page outside of an iFrame to set the cookie - after this the iFrame can load as long as the CORS configuration is correct and the browser isn't completely blocking the iFrame from loading.
I'm not sure how many users are using iFrames that would require cookies to be set, but they would be impacted if any of their users use Safari.
You may try Store.JS. As per the docs:
store.js exposes a simple API for cross browser local storage

Google+ Sign in from Javascript - Invalid Parameter value for origin

I've been going through the steps to add a Google+ Sign-in to my web application as found in https://developers.google.com/+/web/signin/
When used in a 'typical' web site, the 'client side' flow works just fine. Now, I'm trying to integrate this Google+ sign inside PhoneGap. Since PhoneGap runs the web page as a file:// URL, the origin that gets sent in the request is file://. In every other PhoneGap I've written, this hasn't been a problem.
However, when I click the Google+ sign in button from my page in PhoneGap, the origin being sent as file:// causes the following error message:
Error: invalid_request
Invalid parameter value for origin: Missing authority: file://
I went to the Google API console and tried to assign file:// as an authorized Javascript origin. But, of course, it doesn't allow file:// to be entered as an origin.
So I'm wondering if anyone has any insight in how to do this kind of web-style (Javascript) Google+ sign in from within PhoneGap (or from a local web page where there is no server - just a page being run as a file://). I really don't want to have to do the sign-in in native code and then integrate the token back over into the 'PhoneGap' realm since that kind of defeats the purpose of writing the app once for multiple platforms.
My understanding is that you cannot use the standard client-side flow with Cordova/PhoneGap because file:// is not a valid origin.
However, you can use the In-App Browser plugin along with window.open, which will allow to initiate a "standard" client-side flow from within the application. You then listen to events on the opened window to deal with the responses.
The plugin works cross-platform so you won't have to maintain multiple native implementations.
The ng-cordova-oauth library implements this for AngularJS.
For more details about the implementation, see this tutorial for details, as well as the Google OAuth documentation.
For file://, the thing works differently.. try this as your origin: http://localhost:4567
or try this tutorial: here

IE9 Javascript injection issue

I am facing some issue with Javascript injection on IE9 (>Medium-high security). In my application when user wants to add any web page to their bookmarks, they click a link, and it injects a Javascript into that page, this injected javascript grabs all details about page and redirect users to my site.
On IE9, it does not seems to be working with Medium-high security. I suspect this has to do something how IE9 handles cross-site javascript injection. But, was not able to find any relevant information.
Can someone please help or guide me to some related information.
Thanks
You may find this TechNet post useful, especially the row "Allow scripting of Internet Explorer Web browser control".
Apparently Internet Explorer doesn't allow scripts to control the web browser except on Medium-Low and Low security levels. Because of this, you won't be able to redirect the browser unless it's set to one of those two levels.
Perhaps instead of redirecting them you could add some kind of notification to the DOM and give them a link to your website?

Categories

Resources