IdentityServer3 icon indicating copy to clipboard operation
IdentityServer3 copied to clipboard

IE couldn't access to idsrv.session persistant cookie from CheckSession iframe on different domains

Open oclaude opened this issue 9 years ago • 9 comments

Hello,

I have implemented the check session iframe on each client that use IdentityServer. It works well excepts on Internet Explorer because it has a restriction about third party persistant cookies (with expires date) provided from a different domains.

To fix this issue, I thinks that you need to return after login a P3P header to set this policy for IE.

https://blogs.msdn.microsoft.com/ieinternals/2009/08/20/internet-explorer-cookie-internals-faq/

Q7: My site is not receiving cookies when it is running in an IFRAME and the parent page is from a different domain. Why?

A: Internet Explorer has restrictions on “3rd party” cookies. 3rd party cookies are cookies which are set or sent for resources from a different domain than the top-level browsing context. You can easily confirm P3P/Cookie restrictions as the root cause of such issues by temporarily changing IE’s Tools / Options / Privacy setting to “Accept All Cookies”.

In order to allow such cookies to be sent reliably, you should send a P3P header when setting the cookie.

You can use Fiddler’s “Privacy Inspector” to view and analyze any P3P Policy. To learn more about P3P and IE, see my quick P3P guide.

https://blogs.msdn.microsoft.com/ieinternals/2013/09/17/a-quick-look-at-p3p/

Proposition :

/// <summary>
/// Privacy Preferences Project (P3P) serve a compact policy (a "p3p" HTTP header) for all requests
/// P3P provides a standard way for Web sites to communicate about their practices around the collection, 
/// use, and distribution of personal information. It's a machine-readable privacy policy that can be 
/// automatically fetched and viewed by users, and it can be tailored to fit your company's specific policies.
/// </summary>
/// <remarks>
/// More info https://blogs.msdn.microsoft.com/ieinternals/2013/09/17/a-quick-look-at-p3p/
/// </remarks>
public class P3PAttribute : ActionFilterAttribute
{
    /// <summary>
    /// On Action Executing add a compact policy "p3p" HTTP header
    /// </summary>
    /// <param name="filterContext"></param>
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContext.Current.Response.AddHeader("p3p","CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");

        base.OnActionExecuting(filterContext);
    }
}


[P3P]
public class HomeController : Controller
{
...
}

Thank you.

oclaude avatar Mar 17 '16 08:03 oclaude

This is something I'd want to research more. In the meantime you can add your own middleware to emit this header.

https://en.wikipedia.org/wiki/P3P

brockallen avatar Mar 17 '16 12:03 brockallen

This could be a possible cause for the check session issues I've been having.

#2333

parkinsona avatar Apr 10 '16 22:04 parkinsona

@oclaude , have you been able to replicate the issue consistently? Do you get an error message from identity server that says something like "Check session endpoint enabled, but SessionId is missing" ?

We have users receiving this error, but I've never been able to replicate it locally with IE. It happens sporadically for our users, most of which are external.

parkinsona avatar Apr 12 '16 00:04 parkinsona

Hello @parkinsona,

Yes, I was able to reproduce this issue consistently. However, you will not believe me but I'm not able to reproduce it now... Even if I clear all cookies and cache from IE. It should be an inconsistently issue or IE updates? Since that I opened this issue, I have not done anything on our solution...

Steps used in paste to reproduce it :

  1. Open IE (all versions)
  2. Go to RP that use CheckSession : e.g = https://www.xxxx.com
  3. Click on the Login button
  4. You are redirected on Identity Server : e.g = https://www.zzzz.com
  5. Select the "Remember Me" checkbox
  6. After the login process, you are redirected on the RP callback url.
  7. On RP, it checks the Session by calling the CheckSessionEndpoint which return Javascript to the iframe, then the iframe access to idsvr.session cookie to check the session state. But IE could not access to a cookie delivered from a different domain.

In production, this issue has been resolved by deploying all applications on the same domain but each application is hosted on its own subdomain.

I let you informed if I'm able to reproduce it again and If I can find the same error in logs Olivier.

oclaude avatar Apr 12 '16 12:04 oclaude

Hi @oclaude ,

I wonder if our issues are slightly different. My RP & IDSVR are on the same domain, diff subdomains. Eg. identityserver.mydomain.com.au & rp.mydomain.com.au

Also, when you do get that error, does it stop your user's from logging in? When I get it, it happens when being redirected back to the idsvr page for authentication and the idsvr.session cookie has been dropped at some point.

parkinsona avatar Apr 12 '16 22:04 parkinsona

Hi @parkinsona,

My colleague was able to reproduce this issue with IE11 but only from different domains.

When the error appears, the user is redirected to the login page and we can see in the browser console this message " session state changed ". Directly after logging in, when the checksession iframe is evaluated, the window receives a message with event.data = changed.

window.addEventListener("message", function (e) {
    if (e.origin === op_origin) {
        **console.log("session state", e.data);**
        if (e.data === "changed" || e.data === "error") {
            window.clearInterval(timer);
        }
        if (e.data === "changed") {
            // do prompt=none w/id_token_hint to OP
            // check result for same sub
            // if same, update local id_token_hint
            window.parent.postMessage("changed", window.location.protocol + "//" + window.location.host);
        }
    }
});

You should be able to see if this is the same issue by subscribing to OnMessageEvent and if it raised directly after that the user is logged in :

window.onmessage = function (e) {
     if (e.origin === window.location.protocol + "//" + window.location.host && e.data === "changed") {
         console.log("Session changed : remove token and redirectForToken");
         idmTokenManager.removeToken();
     }
 };

oclaude avatar Apr 14 '16 07:04 oclaude

Hi @oclaude ,

I have both the eventListener and OnMessageEvent that you mentioned.

It sounds like your issue happens straight away, as soon as the user logs in? In this scenario, your "removeToken" would effectively log them out of your RP, so the next request to a secured resource would kick them over to IdentityServer.

If that's the case, then mine is a bit different. For my users, they can initially log in, but then after a few days,weeks they'll lose their idsvr.session cookie for some reason. They still have the idsvr cookie, which is why they get an error when they're redirected back to identityserver.

parkinsona avatar Apr 14 '16 22:04 parkinsona

Should work if you set the p3p header to a random word like people says here? Can do that in application config file

http://stackoverflow.com/questions/389456/cookie-blocked-not-saved-in-iframe-in-internet-explorer

jeremy001181 avatar Apr 28 '16 18:04 jeremy001181

Thanks @jeremy001181. It looks like IE just has issues with cookies in general if there's anything out of the ordinary happening. Unfortunately, I'm unable to reliably replicate my issue, so I could implement this, but I won't know if it'll fix the problem.

parkinsona avatar Apr 28 '16 22:04 parkinsona