Scenario:
I have parent site A domain A that embeds an iframe with domain B...note that I have control of both sites. Im calling postMessage from site A that posts some information to be stored as cookie in iframe domain B. The iFrame will listen to the postMessage event and set cookie accordingly.
Domain A:
var frame = document.getElementById('exampleFrame');
frame.contentWindow.postMessage({"age":28}, '*');
Embedded iframe domain B:
window.addEventListener('message', messageReceivedEvent, false);
function messageReceivedEvent(e) {
document.cookie("age=" + e.data.age + ";");
console.log(document.cookie);
}
console.log(document.cookie) returns nothing
The issue here is that, once i set the cookie in the messageReceivedEvent, it seems like the cookie is not stored in domain B. Did I missed out something?
Note: This issue only happened in latest Google Chrome version, Firefox works fine.
Chrome handles cookies differently.
See Mozilla Document.cookie Example #1:
it works perfectly in Firefox
does not work in Chrome
See this SO thread about chrome cookies.
Also, with iFrames other people reported this Chrome "bug" here:
thread on bugs.chromium.org
or here support.google.com thread
Not sure how to solve it, but maybe use localStorage instead?
Related
I wrote an extension that works both on Firefox and on Chrome. That extension injects some code on the page that also does a Get - Request on the same site.
I am on https://example.com/Posts/1234 and try to call another url from the same host:
var docUrl=document.location.href;
$.get(docUrl + '/mentionable.json?q=test', function (response) {
// do something
});
(So the complete url called is https://example.com/Posts/1234/mentionable.json?q=test)
In the chrome extension this works just fine. When I try to run the same code as a Firefox web-extension instead I retrieve a 401 unauthorized response. So my guess would be that chrome sends the authorization-cookie from the current visited site while Firefox does not.
Any way to tell Firefox to use the current authorization?
I found the solution. Firefox requires the following entry in the permissions of the manifest.json:
"https://*/*"
(or the URL you want to connect to) even if it's the same host as the site the extension-js is on. Chrome works without this entry.
we are using a keycloak 1.3.1 authentication library, and I've noticed that once I initialize the keycloak with { onLoad: 'login-required' }, IE (11) gets infinite loop...
Other browsers work fine.
I'm basically doing this:
keycloak.init({ onLoad: 'login-required' }).success(function(authenticated) {
console.info(authenticated ? 'authenticated' : 'not authenticated');
some other stuff...
}).error(function() {
console.warn('failed to initialize');
});
Any idea what's causing it, and to solve this? Trying to install the newest version 1.4.0 now in hopes the weird bug gets solved.
Thanks in advance.
I had the same problem with keycloak v1.5.0.Final / Internet Explorer 11, and finally figured out what is going on.
1. Behind the scene
When using modes 'login-required' or 'check-sso' in Keycloak's init method, Keycloak Javascript Adapter sets an iframe that checks at timed intervals that user is authenticated.
This iframe is retrieved from keycloak's server (let's say http(s)://yourkeycloakhost:port):
http(s)://yourkeycloakhost:port/auth/realms/yourrealm/protocol/openid-connect/login-status-iframe.html?client_id=yourclientid&origin=http(s)://yourorigin
and its content is a javascript script which should be able to access KEYCLOAK_SESSION cookie previously set by keycloak on authentication (on the same domain ie http(s)://yourkeycloakhost:port).
2. The problem with IE
Yes! Here is the problem with Internet Explorer, which has a strict policy with iframes and cookies. Actually, the keycloak iframe does NOT have access to the yourkeycloakhost domain cookies due to its P3P policy (Microsoft Internet Explorer is the only major browser to support P3P).
This problem is well described on this stackoverflow question
3. Resolution
The solution is to make Internet Explorer trust our keycloak's domain (yourkeycloakhost) for using cookies, so that the iframe is able to read the KEYCLOAK_SESSION cookie value, and register it in its data.
To do that, your keycloak server must append HTTP response header with P3P information. You can do that with an apache or nginx proxy that will always set proper headers. I did that with apache and it's mod_headers module:
Header always set P3P "CP=ALL DSP COR CUR ADM PSA CONi OUR SAM OTR UNR LEG"
You can learn more on P3P with W3C and/or validate your P3P Policy with this P3P validator.
4. Consequence
You can have a look at keycloak's iframe code :
var cookie = getCookie('KEYCLOAK_SESSION');
if (cookie) {
data.loggedIn = true;
data.session = cookie;
}
Now the cookie on domain yourkeycloakhost is retrieved correctly by Internet Explorer, and the problem is fixed!
A workaround that worked for me, learnt from keycloak documentation, add the parameter checkLoginIframe when executing init method : .init({onLoad: 'login-required', checkLoginIframe: false})
The Keycloak developers fixed this problem, as described by #François Maturel, in version 1.9.3. See for more information issue #2828.
I need to query a third-party site with ajax. To do so I need cookies, which I retrieve by loading the site's page in a hidden frame. However, I just saw that IE (at least 11) blocks cookies set in frames if the site doesn't provide a P3P policy.
To work around that, I initially thought opening the site in a popup then closing it. But it seems impossible, as the return value of a window.open is null if the url is not from the same domain.
Here's some test code:
var foo = window.open(url);
setTimeout(function(){
foo.close(); // fails in IE as foo is null if url is 3rd-party
}, 2000);
I've seen restrictions, such as Window.close can only close windows created with js (or asks confirmation), but I haven't seen anything regarding cross-domain such as my case. BTW, there's no issue with FF and Chrome. Is there any way to do that?
Ok, so I finally got it. It has nothing to do with same origin policy. The catch is I was testing the above code in a page accessed through a http://localhost/ url. If I access the same page with http://127.0.0.1/ instead, the foo variable is not null and the popup can be closed.
If anyone has any idea why some restrictions in IE apply on localhost and not on 127.0.0.1, you're welcome.
I am using this jquery code
$("#tasksViewType").selectBox().change(
function (){
var userId = $('#hiddenUserId').val();
var viewTypeId = $("#tasksViewType").val();
$.post('updateViewType',{viewType:viewTypeId,userId:userId});
location.reload(true);
});
so this update the view type in database and then refresh the page but in firefox this is not working I tested in chrome and opera this is working fine.
I even tried to put the timer between the 3rd and 4th line but then it update the view type in database but not refresh the page autometically.
Please let me know if you need more detail.
Reload the page in the callback function. Otherwise, the page will reload before the server script has updated the database.
$.post('updateViewType',{viewType:viewTypeId,userId:userId}, function() {
location.reload(true);
});
Set the extension of your page in the post.Like if your page is php type then give it like the following
$.post('updateViewType.php',{viewType:viewTypeId,userId:userId});
A possible reason could be the Cross-origin resource sharing restriction.
In firefox, by default, Cross-site HTTP requests are restricted.
You need to enable enable cross-origin resource sharing explicitly.
You may refer to the following links for more details.
how to get a cross origin resource sharing cors post request working
Enable CORS
For posting AJAX forms in a form with many parameters, I am using a solution of creating an iframe, posting the form to it by POST, and then accessing the iframe's content.
specifically, I am accessing the content like this:
$("some_iframe_id").get(0).contentWindow.document
I tested it and it worked.
On some of the pages, I started getting an "Access is denied" error. As far as I know, this shouldn't happen if the iframe is served from the same domain.
I'm pretty sure it was working before. Anybody have a clue?
If I'm not being clear enough: I'm posting to the same domain. So this is not a cross-domain request. I am testing on IE only.
P.S. I can't use simple ajax POST queries (don't ask...)
Solved it by myself!
The problem was, that even though the correct response was being sent (verified with Fiddler), it was being sent with an HTTP 500 error code (instead of 200).
So it turns out, that if a response is sent with an error code, IE replaces the content of the iframe with an error message loaded from the disk (res://ieframe.dll/http_500.htm), and that causes the cross-domain access denied error.
Beware of security limitations associated to iFrames, like Cross domain restriction (aka CORS). Below are 3 common errors related to CORS :
Load an iFrame with a different domain. (Ex: opening "www.foo.com" while top frame is "www.ooof.com")
Load an iFrame with a different port: iFrame's URL port differs from the one of the top frame.
Different protocols : loading iFrame resource via HTTPS while parent Frame uses HTTP.
My issue was the X-Frame-Options HTTP header. My Apache configuration has it set to:
Header always append X-Frame-Options DENY
Removing it allowed it to work. Specifically in my case I was using iframe transport for jQuery with the jQuery file upload plugin to upload files in IE 9 and IE 10.
I know this question is super-old, but I wanted to mention that the above answer worked for me: setting the document.domain to be the same on each of the pages-- the parent page and the iframe page. However in my search, I did find this interesting article:
http://softwareas.com/cross-domain-communication-with-iframes
Note if you have a iframe with src='javascript:void(0)' then javascript like frame.document.location =... will fail with Access Denied error in IE. Was using a javascript library that interacts with a target frame. Even though the location it was trying to change the frame to was on the same domain as parent, the iframe was initially set to javascript:void which triggered the cross domain access denied error.
To solve this I created a blank.html page in my site and if I need to declare an iframe in advance that will initially be blank until changed via javascript, then I point it to the blank page so that src='/content/blank.html' is in the same domain.
Alternatively you could create the iframe completely through javascript so that you can set the src when it is created, but in my case I was using a library which reqired an iframe already be declared on the page.
Basically, this error occurs when the document in frame and outside of ii have different domains. So to prevent cross-side scripting browsers disable such execution.
if it is a domain issue (or subdomain) such as www.foo.com sending a request to www.api.foo.com
on each page you can set the
document.domain = www.foo.com
to allow for "cross-domain" permissions