aspnet / AspNetKatana

Microsoft's OWIN implementation, the Katana project
Apache License 2.0
959 stars 331 forks source link

Session in ASP.NET WebForm is cleared after authenticated by Entra ID with CookieAuthentication and WsFederationAuthentication #518

Closed yooontheearth closed 5 months ago

yooontheearth commented 5 months ago

Hello,

I just figured out that Session is cleared right after redirecting back from authenticating by Entra ID with CookieAuthentication and WsFederationAuthentication when I use Global.asax together. Without Global.asax, there is no problem. Assembly version is 4.2.2.

I use Global.asax to enable Session for WebAPI request (Not in the example though), so it is not an option to remove it for Entra ID authentication. Do you have any ideas to make it work?

I am not sure to be ok to attach a sample here but I made a minimum working example, so I will be appreciated if you would take a look at the example. EntraIdAuthTest.zip

How to reproduce On chrome incognito mode, navigate to Test2.aspx which sets Session["Test"] and redirects to Test1.aspx. Test1.aspx shows Session ID and Session["Test"] value. Then you navigate to Authentication.aspx which challenges to Entra ID and redirects back from there. At that time, Session ID is already different from the one at the Test1 shown.

Tratcher commented 5 months ago

@yooontheearth unfortunately this product is not under active development. We may consider PRs, but don't expect feature work or investigations at this point. I recommend StackOverflow for this class of question.

yooontheearth commented 5 months ago

@Tratcher thank you for letting me know about it. I'll ask at StackOverflow then.

Edit I could make Session work as using PreApplicationStartMethod and HttpModule instead of doing stuff in Global.asax. I'll share the code for those who might need it.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Resources;
using System.Web;
using System.Web.Http;
using System.Web.Routing;
using System.Web.UI;
using Newtonsoft.Json.Serialization;
using System.Web.SessionState;

[assembly: PreApplicationStartMethod(typeof(AppStartup), "Initialize")]

namespace Test
{
    public static class AppStartup
    {
        // Equivalent to protected void Application_Start(object sender, EventArgs e) in Global.asax
        public static void Initialize()
        {
            // Do something for start app if you want

            // Register a module to do something on every request
            HttpApplication.RegisterModule(typeof(AppHttpModule));
        }
    }

    internal sealed class AppHttpModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.PostAuthorizeRequest += Context_PostAuthorizeRequest;   
        }

        private void Context_PostAuthorizeRequest(object sender, EventArgs e)
        {
            // Enable session if it's for web api
            if (IsWebApiRequest())
            {
                System.Web.HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
            }
        }

        private bool IsWebApiRequest()
        {
            return System.Web.HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith("~/api");
        }

        public void Dispose()
        {
        }
    }
}