Authentication LS 2011 web应用程序中的自有广告表单身份验证问题

Authentication LS 2011 web应用程序中的自有广告表单身份验证问题,authentication,web,visual-studio-lightswitch,Authentication,Web,Visual Studio Lightswitch,我在使用表单身份验证的LightSwitch 2011 web应用程序中遇到问题 我已经实现了自己的登录屏幕,它根据active directory对用户进行身份验证。我的代码还检查用户是否被分配到特定的active directory组,以确定他们是否可以添加/编辑/删除数据 登录表单位于login.aspx页面上。登录按钮包含以下代码: protected void buttonLogin_Click(object sender, EventArgs e) { LdapAuthent

我在使用表单身份验证的LightSwitch 2011 web应用程序中遇到问题

我已经实现了自己的登录屏幕,它根据active directory对用户进行身份验证。我的代码还检查用户是否被分配到特定的active directory组,以确定他们是否可以添加/编辑/删除数据

登录表单位于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;
}
例如,
可以为一个表执行
方法

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();
}
网络配置

<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>

s name=“.ASPXAUTH”
loginUrl=“Login.aspx”
保护=“全部”
超时=“30”
path=“/”
requireSSL=“false”
slidengexpiration=“true”
defaultUrl=“Home.aspx”
cookieless=“UseUri”/>
问题

  • 问题在于,如果用户空闲时间超过
    超时时间
    ,会话将超时。因此,会话令牌
    isUserAdmin
    NULL
    。此时,我希望应用程序返回到登录屏幕。
    Response.Redirect
    Server.Transfer
    IsCurrentUserAdmin()
    方法中不起作用。如果会话令牌
    isUserAdmin
    NULL
    ,如何让应用程序将用户返回登录屏幕?!记住,会话令牌是在
    login.aspx
    页面代码隐藏中设置的

  • 当用户关闭Lightswitch应用程序的最后一个选项卡时,该应用程序将打开一个新选项卡并浏览登录页面,用户将自动登录,而无需在
    login.aspx
    页面上处理登录过程。这意味着会话令牌
    isUserAdmin
    NULL
    。即使用户在关闭应用程序的最后一个选项卡之前尚未登录,也会发生这种情况。这又导致了问题1


  • 提前谢谢

    如果我正确理解您的问题,如果出于任何原因,
    isUserAdmin
    设置为
    NULL
    ,您希望将用户返回到登录屏幕

    在我的应用程序中,我只需使用一个按钮,用户可以单击该按钮注销。但是在您的案例中,底层方法应该是一样的

    首先创建一个名为LogOff.aspx的新页面。对于页面本身,您可以保留默认生成的代码:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
    
        </div>
        </form>
    </body>
    </html>
    
    这是我使用按钮的代码。但是,如果您选择
    调度程序调用
    导航
    的部分,并将其放在
    IsCurrentUserAdmin()
    方法中,它应该执行相同的操作(再次检查C#):

    根据我的经验,在Lightswitch中有一点问题。如果按原样执行,您可能会收到以下信息:

    “/”应用程序中出现服务器错误。

    找不到资源

    说明:HTTP 404。您正在寻找的资源(或其 依赖项)可能已被删除、名称已更改或 暂时不可用。请查看下面的URL并进行修改 确保它拼写正确

    请求的URL:/LogOff.aspx

    解决办法是:

    首先在解决方案资源管理器中右键单击项目名称,然后卸载项目。卸载项目后,右键单击它并编辑project_name.lsproj
    Ctrl+F
    用于
    default.htm
    。您正在查找由
    \u BuildFile
    执行的部分。将该节从
    \u BuildFile
    复制到
    /\u BuildFile
    ,粘贴到该节下方,并按如下方式修改

    <_BuildFile Include="Server/LogOff.aspx">
      <SubFolder>
      </SubFolder>
      <PublishType>
      </PublishType>
    </_BuildFile>
    
    
    
    现在右键单击并重新加载项目。如果尝试构建时出现错误,请尝试构建|清理并重新构建。如果在Debug中运行应用程序,此代码将重新加载页面。但一旦您发布并随后导致
    isUserAdmin
    NULL
    时,代码应将您注销,并将您带回登录屏幕

    参考文献:

    public bool IsCurrentUserAdmin()
    {
        if (HttpContext.Current.Session["isUserAdmin"] == null)
            return false;
    
        return (bool)(HttpContext.Current.Session["isUserAdmin"]);
    }
    


    感谢您的回复。该方法不适用于我的实施。问题是我无法使用HtmlPage.Window.Navigate,因为我无法引用System.Windows.Browser。为了说明问题,这里实现了IsCurrentUserAdmin()方法(链接到图片以说明问题):也许我的方法不正确,我必须重新考虑它?!也许我的解决方案是过分的。如果您只需调用
    FormsAuthentication.SignOut();Response.Redirect(“default.htm”)来自
    IsCurrentUserAdmin()
    或者甚至在
    CanExecute
    代码本身中?这应该只需要
    System.Web.Security
    ,它应该在
    DataService
    code中提供。这就是我尝试过的。。但它没有效果。该站点只是加载,不重定向到登录页面。。我不知道为什么,但我想我将来会避免ls您正在调试模式下运行吗?正如我提到的,该代码将以调试模式重新加载页面。您需要发布才能正常注销。此外,由于您的主要问题是从Active Directory获取有关用户组的信息,请尝试升级到2012 RC。他们在测试版中增加了对的支持。使用内置权限应该比尝试使用自己的安全性容易得多。
    using Microsoft.LightSwitch.Threading;
    using System.Windows.Browser;
    
            partial void btnLogOff_Execute()
            {
                Dispatchers.Main.Invoke(() =>
                {
                    HtmlPage.Window.Navigate(new Uri("LogOff.aspx", UriKind.Relative));
                });
            }
    
    <_BuildFile Include="Server/LogOff.aspx">
      <SubFolder>
      </SubFolder>
      <PublishType>
      </PublishType>
    </_BuildFile>