Context.User lost after Redirect

81 views Asked by At

I am trying to integrate OAuth into some ASP.NET legacy code.

For this I am using OWIN. I'm already able to open the External Provider login page, redirect back to my application and retrieve the account details, but I am having problems on how to keep the user authenticated in the subsequent http requests.

My initial flow is the following:

  1. I open the Login.aspx page (from my web application);
  2. I click a button to login using an External Provider;
  3. In the External Provider login page, I introduce my credentials and click Confirm;
  4. The credentials get validated and I get redirected to LoginExternal.aspx page (from my web application);

In LoginExternal.aspx, I have the following Page_Load logic:

    protected void Page_Load()
    {
        if (!IsPostBack)
        {
            var loginInfo = Context.GetOwinContext().Authentication.GetExternalLoginInfo();
            LogInOAuth(loginInfo.Email);
        }
    }

The loginInfo object is correclty filled and contains the data returned by the external provider, including the email address.

In the LogInOAuth method I do the following:

    private void LogInOAuth(string email)
    {
        var id = new BusUser().getIdByUserEmail(email);

        if (id > 0)
        {
            Session.Add("userID", id);

            Context.User = new CustomUserPrincipal(false, 0, new UserDetails()
            {
                ID = id.ToString(),
                Name = email
            });

            var data = UserDetails.EncondeUserData(new object[] { id.ToString(), email });

            CreateCookie(data, "MyAppName", DateTime.Now.AddMinutes(60));

            Response.Redirect("Default.aspx", false);
        }
    }

After setting the Context.User, if I do Request.IsAuthenticated I get true.

The CreateTicket will create a cookie with the user info.

    private bool CreateCookie(string username, string type, DateTime cookieTime)
    {
        FormsAuthentication.Initialize();

        var ticket = new FormsAuthenticationTicket(1, username, DateTime.Now, cookieTime, true, type, FormsAuthentication.FormsCookiePath);

        try
        {
            Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
        }
        catch (Exception) { }

        var hash = FormsAuthentication.Encrypt(ticket);
        var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);

        if (ticket.IsPersistent)
            cookie.Expires = ticket.Expiration;

        HttpContext.Current.Response.Cookies.Add(cookie);

        return true;
    }

The cookie is also correctly created, as I can see it in the browser.

My issue is after the redirect to Default.aspx. In this page I perform a validation to check if the user is authenticated, by doing Request.IsAuthenticated, which returns false and redirects me to the Login.aspx page.

The Context.User is getting cleaned, which is why Request.IsAuthenticated return false. I was hopping that someone could tell me why this happens and how to fix this.

Other code that might be important:

My OAuth configuration in the Startup:

    public static void Configure(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Login.aspx")
        });
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        app.UseFacebookAuthentication(appId: "...", appSecret: "...");
    }

My web config is:

<authentication mode="None"/>

Note:

Initially I was trying to integrate the OAuth using the <authentication mode="Forms">, but I was always getting redirected to the login page. I believe this happened because my web application didn't recognized the External Provider URL, so it redirected me to the login.aspx page. I tried to add it as an exception using the location tags in web.config but no success.

0

There are 0 answers