asp.net手动设置FormsAuthentication Cookie会丢失站点母版页上的userData

时间:2019-01-04 20:10:53

标签: asp.net cookies forms-authentication

我已经花了一整天的时间进行研究和重新编码,但我无法使其正常工作。我创建了一个网站,允许用户使用其Active Directory用户ID(sAMAccountName)或电子邮件地址(userPrincipalName)登录。它正在读取AD,验证用户并将userData存储在cookie中。在此过程中,我已经检查了好几次,数据一直保留在cookie中,直到它到达我的网站主页为止。

web.config看起来像这样:

<authentication mode="Forms">
  <forms loginUrl="~/login.aspx" slidingExpiration="true" defaultUrl="default.aspx" name=".ADAuthCookie" timeout="864000" />
</authentication>
<membership defaultProvider="MyADMembershipProvider_PrincipalName">
  <providers>
    <clear />
    <add name="MyADMembershipProvider_AccountName" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" attributeMapUsername="sAMAccountName" />
    <add name="MyADMembershipProvider_PrincipalName" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" attributeMapUsername="userPrincipalName" />
  </providers>
</membership>

用户输入其信息并点击“登录”按钮,此功能将触发:

protected void Login_Click(object sender, CommandEventArgs e)
{
    authCookie ac = new authCookie();
    myUtils mu = new myUtils();

    string userID = (LoginUser.FindControl("UserName") as TextBox).Text;
    string userPW = (LoginUser.FindControl("Password") as TextBox).Text;

    MembershipProvider dp;

    //Search for @ in the value typed into the User ID box to see if they are logging
    //in using their e-mail address or User ID, and assign the appropriate AD lookup
    int amper = userID.IndexOf("@");

    switch (amper)
    {
        case -1:    //login id used
            dp = Membership.Providers["MyADMembershipProvider_AccountName"];
            break;
        default:    //email address used
            dp = Membership.Providers["MyADMembershipProvider_PrincipalName"];
            break;
    }

    //Verify if the user is in Active Directory or that Jimmy is debugging...
    if ((dp.ValidateUser(userID, userPW)) || (HttpContext.Current.Request.IsLocal))
        ac.cookiePrep(LoginUser);
    else if (mu.isTestAccount(userID, userPW))  //someone is logging in with a testAccount
        ac.cookiePrep(LoginUser);
    else
    {
        ((Label)LoginUser.FindControl("accessDenied")).Visible = true;
        Response.Write("Invalid UserID and Password");
    }
}

被调用的ac.cookiePrep方法如下:

public void cookiePrep(Login LoginUser)
{
    string userData = "unknown|unknown";

    // Concat the values into a single string to pass into the cookie
    userData = getUserData(LoginUser.UserName);

    // Create the cookie that contains the forms authentication ticket
    HttpCookie authCookie = FormsAuthentication.GetAuthCookie(LoginUser.UserName, LoginUser.RememberMeSet);

    // Get the FormsAuthenticationTicket out of the encrypted cookie
    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
    FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(2,
                                                                        ticket.Name,
                                                                        ticket.IssueDate,
                                                                        ticket.Expiration,
                                                                        LoginUser.RememberMeSet,
                                                                        userData,
                                                                        ticket.CookiePath);

    // Manually add the authCookie to the Cookies collection
    authCookie.Value = FormsAuthentication.Encrypt(newTicket);
    HttpContext.Current.Response.Cookies.Add(authCookie);

    //string redirUrl = FormsAuthentication.GetRedirectUrl(LoginUser.UserName, LoginUser.RememberMeSet);

    //if (redirUrl == null)
        //redirUrl = "../default.aspx";

    //HttpContext.Current.Response.Redirect(redirUrl, false);
}

我在Login_click函数的最后调用了cookie,以验证userData是否仍然存在。此时,无论使用什么重定向魔术,都会发生,并且用户将重定向到默认/主页,在该页面上将调用站点母版页。此时,我在第一个调用的函数的顶部插入了对cookie的调用,而userData丢失了。

protected void Page_Init(object sender, EventArgs e)
{
    HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    {
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
    }

    // The code below helps to protect against XSRF attacks
    var requestCookie = Request.Cookies[AntiXsrfTokenKey];
    Guid requestCookieGuidValue;
    if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
    {
        // Use the Anti-XSRF token from the cookie
        _antiXsrfTokenValue = requestCookie.Value;
        Page.ViewStateUserKey = _antiXsrfTokenValue;
    }
    else
    {
        // Generate a new Anti-XSRF token and save to the cookie
        _antiXsrfTokenValue = Guid.NewGuid().ToString("N");
        Page.ViewStateUserKey = _antiXsrfTokenValue;

        var responseCookie = new HttpCookie(AntiXsrfTokenKey)
        {
            HttpOnly = true,
            Value = _antiXsrfTokenValue
        };
        if (FormsAuthentication.RequireSSL && Request.IsSecureConnection)
        {
            responseCookie.Secure = true;
        }
        Response.Cookies.Set(responseCookie);
    }

    Page.PreLoad += master_Page_PreLoad;
}

所以这就是奇怪的地方……或者也许这是问题所在,我只是没有意识到。如果用户使用其用户ID登录,则userData不会丢失。但是,如果他们注销并尝试使用其电子邮件地址重新登录,那么userData就会在母版页上丢失。

我一直在阅读并且没有使用GetRedirectURL方法(您可以看到它已被注释掉),并且我正在使用Response.Add,使用Request抓取cookie ...人们提到的所有陷阱。我无法弄清楚为什么使用电子邮件似乎会使userData消失了。

有什么建议吗?

0 个答案:

没有答案