我有一个asp.net/c#应用程序,该应用程序使用MembershipProvider和FormsAuthentication来验证用户在Active Directory中,创建一个cookie并重定向回他们来自的页面。
如果用户使用其userID(活动目录cn)登录,则将其通过Membership.ValidateUser传递,如果成功,则使用FormsAuthentication.GetRedirectURL创建cookie并将其重定向回其原始页面。效果很好,完全符合预期。
但是,如果用户使用他们的电子邮件地址登录,那么我将通过在数据库中进行查找来将他们的电子邮件地址换成他们的userID。那时,使用的代码与上述相同,但是由于某种原因,重定向失败,并且我的网站停留在“登录”页面上。
您可以在下面的代码中看到,我什至尝试将FormsAuthentication.GetRedirectURL与SetAuthCookie和Response.Redirect换出,它的工作原理仍然如上所述。
我认为电子邮件地址的长度可能会导致Cookie的大小过大,但该大小小于500,未接近4096个限制。
有人以前见过这样的东西吗?有什么建议吗?
protected void Login_Click(object sender, CommandEventArgs e)
{
myUtils mu = new myUtils();
string userID = (LoginUser.FindControl("UserName") as TextBox).Text;
string userPW = (LoginUser.FindControl("Password") as TextBox).Text;
bool remMe = (LoginUser.FindControl("RememberMe") as CheckBox).Checked;
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 if they are using their email
//address get their ID and continue processing with it
if (userID.IndexOf("@") > 0)
userID = mu.getUserIDByEmailAddress(userID);
dp = Membership.Providers["MyADMembershipProvider_AccountName"];
//Verify if the user is in Active Directory or that Jimmy is debugging...
//if ((dp.ValidateUser(userID, userPW)) || (HttpContext.Current.Request.IsLocal))
if (
(dp.ValidateUser(userID, userPW)) //User is in active directory
|| (mu.isTestAccount(userID, userPW)) //User is logging in with a test account
) {
mu.getUserData(userID);
FormsAuthentication.SetAuthCookie(userID, remMe);
string url = FormsAuthentication.GetRedirectUrl(userID, false);
Response.Redirect(url, false);
//FormsAuthentication.RedirectFromLoginPage(userID, remMe);
}
else
{
((Label)LoginUser.FindControl("accessDenied")).Visible = true;
Response.Write("Invalid UserID and Password");
}
}
答案 0 :(得分:-1)
真是一段旅程。如前所述,它是在asp.net中开发的。 Login.aspx页面正在使用大多数原始模板元素,包括原始asp:Login控件:
<asp:Login ID="LoginUser" runat="server" ViewStateMode="Disabled" RenderOuterTable="false">
<LayoutTemplate>
<p class="validation-summary-errors" runat="server">
<asp:Literal runat="server" ID="FailureText" />
<asp:Label ID="accessDenied" Font-Size="Large" ForeColor="red" CssClass="accessDeniedLabel" Visible="false" runat="server" >
Only JCPS employees that are teachers, administrators, counselors, or support staff may enter the <strong>"Staff Only"</strong>
sections of the DMC.
</asp:Label>
</p>
<fieldset>
<legend>Log in Form</legend>
<ol>
<li>
<asp:Label ID="Label1" runat="server" AssociatedControlID="UserName">User name:</asp:Label>
<asp:TextBox runat="server" ID="username" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="UserName" CssClass="field-validation-error" ErrorMessage="The user name field is required." />
</li>
<li>
<asp:Label ID="Label2" runat="server" AssociatedControlID="Password">Password</asp:Label>
<asp:TextBox runat="server" ID="Password" TextMode="Password" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="Password" CssClass="field-validation-error" ErrorMessage="The password field is required." />
</li>
<li>
<asp:CheckBox runat="server" ID="RememberMe" />
<asp:Label runat="server" ID="cbRememberMe" AssociatedControlID="RememberMe" CssClass="checkbox">Remember me on this device?</asp:Label>
</li>
</ol>
<asp:Button ID="Button1" runat="server" CommandName="Login" Text="Log in" OnCommand="Login_Click" />
</fieldset>
</LayoutTemplate>
</asp:Login>
在用户输入凭据并单击“登录”按钮后,它将发送到Login方法。如果用户使用其userID登录,我将针对活动目录进行验证,设置cookie并重定向。这很完美。如果用户使用其电子邮件地址登录,则在我上面发布的原始功能中,我将查找其userID,然后继续沿路径进行操作以验证其是否位于活动目录中。这导致重定向无法正常工作。
我已经修改了过程,以包括额外的一行代码-在获取用户ID之后,在我只允许发送电子邮件之前,我将LoginUser.UserName字段中的值也更改为用户ID。解决行程问题,因为如果您看一下该程序,那么我不会在其他任何地方使用它,并且认为这并不重要。显然可以,更改LoginUser.UserName字段以匹配userID允许重定向开始工作。因此,显然在幕后有一些魔术,其中asp.net会将传递到FormsAuthentication票证中的ID与实际位于asp.net:Login控件中的文本匹配,如果它们不匹配,我猜只是将其重定向回“登录”页面。
希望这将帮助其他尝试获得登录名的用户接受用户ID或电子邮件地址...
protected void Login_Click(object sender, CommandEventArgs e)
{
myUtils mu = new myUtils();
string userID = LoginUser.UserName;
string userPW = LoginUser.Password;
bool remMe = (LoginUser.FindControl("RememberMe") as CheckBox).Checked;
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 if they are using their email
//address get their ID and continue processing with it
if (userID.IndexOf("@") > 0)
{
userID = mu.getUserIDByEmailAddress(userID);
LoginUser.UserName = userID;
}
dp = Membership.Providers["MyADMembershipProvider_AccountName"];
//Verify the user is in Active Directory, it's a test account, or that Jimmy is debugging...
if (
(dp.ValidateUser(userID, userPW)) //User is in active directory
|| (mu.isTestAccount(userID, userPW) //User is logging in with a test account
|| (HttpContext.Current.Request.IsLocal)) //Debugging, doesn't really matter...
) {
mu.getUserData(userID);
FormsAuthentication.RedirectFromLoginPage(userID, remMe);
}
else
{
((Label)LoginUser.FindControl("accessDenied")).Visible = true;
Response.Write("Invalid UserID and Password");
}
}