ASP.NET_SessionId + OWIN Cookies do not send to browser

后端 未结 9 1258
误落风尘
误落风尘 2020-11-22 14:00

I have a strange problem with using Owin cookie authentication.

When I start my IIS server authentication works perfectly fine on IE/Firefox and Chrome.

I st

9条回答
  •  情话喂你
    2020-11-22 14:20

    Katana team answered to the issue Tomas Dolezar raised, and posted documentation about workarounds:

    Workarounds fall into two categories. One is to re-configure System.Web so it avoids using the Response.Cookies collection and overwriting the OWIN cookies. The other approach is to re-configure the affected OWIN components so they write cookies directly to System.Web's Response.Cookies collection.

    • Ensure session is established prior to authentication: The conflict between System.Web and Katana cookies is per request, so it may be possible for the application to establish the session on some request prior to the authentication flow. This should be easy to do when the user first arrives, but it may be harder to guarantee later when the session or auth cookies expire and/or need to be refreshed.
    • Disable the SessionStateModule - If the application is not relying on session information, but the session module is still setting a cookie that causes the above conflict, then you may consider disabling the session state module.
    • Reconfigure the CookieAuthenticationMiddleware to write directly to System.Web's cookie collection.
    app.UseCookieAuthentication(new CookieAuthenticationOptions
                                    {
                                        // ...
                                        CookieManager = new SystemWebCookieManager()
                                    });
    

    See SystemWebCookieManager implementation from the documentation (link above)

    More information here

    Edit

    Below the steps we took to solve the issue. Both 1. and 2. solved the problem also separately but we decided to apply both just in case:

    1. Use SystemWebCookieManager

    2. Set the session variable:

    protected override void Initialize(RequestContext requestContext)
    {
        base.Initialize(requestContext);
    
        // See http://stackoverflow.com/questions/20737578/asp-net-sessionid-owin-cookies-do-not-send-to-browser/
        requestContext.HttpContext.Session["FixEternalRedirectLoop"] = 1;
    }
    

    (side note: the Initialize method above is the logical place for the fix because base.Initialize makes Session available. However, the fix could also be applied later because in OpenId there's first an anonymous request, then redirect to the OpenId provider and then back to the app. The problems would occur after the redirect back to the app while the fix sets the session variable already during the first anonymous request thus fixing the problem before any redirect back even happens)

    Edit 2

    Copy-paste from the Katana project 2016-05-14:

    Add this:

    app.UseCookieAuthentication(new CookieAuthenticationOptions
                                    {
                                        // ...
                                        CookieManager = new SystemWebCookieManager()
                                    });
    

    ...and this:

    public class SystemWebCookieManager : ICookieManager
    {
        public string GetRequestCookie(IOwinContext context, string key)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
    
            var webContext = context.Get(typeof(HttpContextBase).FullName);
            var cookie = webContext.Request.Cookies[key];
            return cookie == null ? null : cookie.Value;
        }
    
        public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }
    
            var webContext = context.Get(typeof(HttpContextBase).FullName);
    
            bool domainHasValue = !string.IsNullOrEmpty(options.Domain);
            bool pathHasValue = !string.IsNullOrEmpty(options.Path);
            bool expiresHasValue = options.Expires.HasValue;
    
            var cookie = new HttpCookie(key, value);
            if (domainHasValue)
            {
                cookie.Domain = options.Domain;
            }
            if (pathHasValue)
            {
                cookie.Path = options.Path;
            }
            if (expiresHasValue)
            {
                cookie.Expires = options.Expires.Value;
            }
            if (options.Secure)
            {
                cookie.Secure = true;
            }
            if (options.HttpOnly)
            {
                cookie.HttpOnly = true;
            }
    
            webContext.Response.AppendCookie(cookie);
        }
    
        public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }
    
            AppendResponseCookie(
                context,
                key,
                string.Empty,
                new CookieOptions
                {
                    Path = options.Path,
                    Domain = options.Domain,
                    Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
                });
        }
    }
    

提交回复
热议问题