我使用表单身份验证的LightSwitch 2011 Web应用程序出现问题。LS 2011 Web应用程序中自己的AD表单身份验证问题
我已经实现了我自己的登录屏幕,可以根据活动目录对用户进行身份验证。我的代码还会检查用户是否分配给特定的活动目录组,以决定是否可以添加/编辑/删除数据。
登录表单放置在Login.aspx页面上。登录按钮保持以下代码:
protected void buttonLogin_Click(object sender, EventArgs e)
{
LdapAuthentication authentication = new LdapAuthentication();
try
{
bool isUserAdmin = false;
if (authentication.IsUserAuthenticated(textBoxUserName.Text, textBoxPassword.Text, ref isUserAdmin))
{
FormsAuthenticationTicket authenticationTicket = new FormsAuthenticationTicket(1,
textBoxUserName.Text, DateTime.Now, DateTime.Now.AddSeconds(1), false, String.Empty);
//Encrypt the ticket.
string encryptedTicket = FormsAuthentication.Encrypt(authenticationTicket);
//Create a cookie, and then add the encrypted ticket to the cookie as data.
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
//Add the cookie to the outgoing cookies collection.
Response.Cookies.Add(authCookie);
//If the everyoneAdmin is set to true the validation of the administratorgroup
//is decativated so we have to grant the current user administrator rights
if (everyoneAdmin)
isUserAdmin = true;
Session["isUserAdmin"] = isUserAdmin ;
Response.Redirect("default.htm");
}
}
catch (Exception ex)
{
labelError.Text = ex.Message;
labelError.Visible = true;
textBoxPassword.Text = String.Empty;
}
}
public bool IsUserAuthenticated(String userName, String password, ref bool isUserAdmin)
{
if (String.IsNullOrEmpty(userName) || String.IsNullOrEmpty(password))
return false;
String domain = String.Empty;
if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["Domain"]))
domain = Convert.ToString(ConfigurationManager.AppSettings["Domain"]).Trim();
else
throw new NullReferenceException("The Domain in the configuration must not be null!");
String ldpa = String.Empty;
if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["LDPA"]))
ldpa = String.Format("LDAP://{0}", Convert.ToString(ConfigurationManager.AppSettings["LDPA"]).Trim());
else
throw new NullReferenceException("The LDPA in the configuration must not be null!");
String administrationGroup = String.Empty;
if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["AdministratorGroup"]))
administrationGroup = Convert.ToString(ConfigurationManager.AppSettings["AdministratorGroup"]).Trim();
else
throw new NullReferenceException("The AdministrationGroup in the configuration must not be null!");
String domainUserName = String.Format(@"{0}\{1}", domain.Trim(), userName.Trim());
DirectoryEntry directoryEntry = new DirectoryEntry(ldpa, domainUserName, password);
try
{
//Bind to the native AdsObject to force authentication.
object obj = directoryEntry.NativeObject;
DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry);
directorySearcher.Filter = String.Format("(SAMAccountName={0})", userName.Trim());
directorySearcher.PropertiesToLoad.Add("cn");
directorySearcher.PropertiesToLoad.Add("memberOf");
SearchResult directorySearchResult = directorySearcher.FindOne();
//unable to find a user with the provided data
if (directorySearchResult == null)
return false;
if (directorySearchResult.Properties["memberof"] != null)
{
//If the memberof string contains the specified admin group
for (int i = 0; i < directorySearchResult.Properties["memberof"].Count; i++)
{
string temp = directorySearchResult.Properties["memberof"].ToString();
// get the group name, for example:
if (directorySearchResult.Properties["memberof"].ToString().ToLower().Contains(administrationGroup.ToLower()))
{
isUserAdmin = true;
break;
}
}
}
}
catch (Exception ex)
{
throw new Exception(String.Format("Error authenticating user.\n\rMessage:\n\r {0}", ex.Message));
}
return true;
}
在保持我实现以下方法CanExcecute
(服务器层)方法的类:
public bool IsCurrentUserAdmin()
{
if (HttpContext.Current.Session["isUserAdmin"] == null)
return false;
return (bool)(HttpContext.Current.Session["isUserAdmin"]);
}
例如, CanExcecute
方法为一个表
partial void dtFacilities_CanDelete(ref bool result)
{
result = this.IsCurrentUserAdmin();
}
partial void dtFacilities_CanInsert(ref bool result)
{
result = this.IsCurrentUserAdmin();
}
partial void dtFacilities_CanUpdate(ref bool result)
{
result = this.IsCurrentUserAdmin();
}
个WebConfig
<authentication mode="Forms">
<form>s name=".ASPXAUTH"
loginUrl="Login.aspx"
protection="All"
timeout="30"
path="/"
requireSSL="false"
slidingExpiration="true"
defaultUrl="Home.aspx"
cookieless="UseUri" />
</authentication>
<authorization>
<deny users="?">
</deny></authorization>
问题:
的问题是,如果用户空闲的时间超过了
timeout
会话超时长。所以,会话令牌isUserAdmin
是NULL
。此时我希望应用程序返回到登录屏幕。 AResponse.Redirect
和Server.Transfer
在IsCurrentUserAdmin()
方法中不起作用。如果会话令牌isUserAdmin
为NULL
?我怎样才能让应用程序将用户返回到登录屏幕?请记住,会话令牌设置在login.aspx
页面代码后面当用户关闭Lightswitch应用程序的最终选项卡时,应用程序将打开一个新选项卡并浏览过去的登录页面,并自动登录而不处理登录过程在
login.aspx
页面。这意味着会话令牌isUserAdmin
是NULL
。即使用户在关闭应用程序的最终选项卡之前尚未登录,也会发生这种情况。这又导致问题1.
在此先感谢!
感谢您的答复的方法不会对我实施工作。问题是,我不能使用HtmlPage.Window.Navigate,因为我不能引用System.Windows.Browser。为了清楚起见,在这里实现了IsCurrentUserAdmin()方法(链接到一张图片来清除它):也许我的方法不是正确的方式,我必须重新考虑它?! –
2012-08-13 14:19:35
也许我的解决方案是过度杀伤。如果你只是调用'FormsAuthentication.SignOut(); Response.Redirect(“default.htm”);'来自'IsCurrentUserAdmin()',甚至是'CanExecute'代码本身?这应该只需要'System.Web.Security',它应该在'DataService'代码中可用。 – 2012-08-13 15:32:15
这就是我试过的......但它不起作用。该网站只是加载,并没有重定向到登录页面..我不知道为什么,但我想我会在未来避免ls。 :) – 2012-08-13 16:30:45