1

我有一个奇怪的 asp.net webforms 网站问题。它是在 vs2008 中开发的,带有表单身份验证和 mysql 后端。它在开发系统(win7)和可能的生产服务器上运行良好。

在新的 2008 R2 服务器上,它的行为很奇怪。当我通过登录页面登录时,它会正确重定向到默认页面,但不会生成用户菜单。但是,如果我回收应用程序池并刷新页面,菜单就会出现并且工作正常。如果注销并登录,再次出现同样的问题,直到应用程序池回收之前没有菜单。

从日志看来,它似乎没有从数据库中获取值。即使有数据。它显示 httpcontext 的正确用户名并显示用户已通过身份验证。并且日志、事件日志等中没有显示错误。

不知道这里发生了什么。

更新 :

我正在使用 log4net 和日志信息进行日志记录。代码中可能有问题。

这里是 web.config 的一部分

  <connectionStrings>
   <add name="tmsConnectionString" connectionString="server=localhost;user id=root;password=54545;persist security info=false;database=tms;port=3306;convert zero datetime=yes;Allow Zero Datetime=True" providerName="MySql.Data.MySqlClient" />
    <add name="archiveConnectionString" connectionString="server=localhost;user id=root;password=55645;database=archive;persist security info=True;port=3306;convert zero datetime=yes;Allow Zero Datetime=True" providerName="MySql.Data.MySqlClient" />
  </connectionStrings>
  <system.web>
    <roleManager enabled="true" cookieName=".ASPROLES" defaultProvider="MySqlRoleProvider" cacheRolesInCookie="false">
      <providers>
        <clear />
        <add connectionStringName="tmsConnectionString" applicationName="tms" writeExceptionsToEventLog="true" name="MySqlRoleProvider" type="Andri.Web.MySqlRoleProvider" />
      </providers>
    </roleManager>
    <membership defaultProvider="MySqlMembershipProvider" userIsOnlineTimeWindow="15">
      <providers>
        <clear />
        <add name="MySqlMembershipProvider" type="Andri.Web.MySqlMembershipProvider" connectionStringName="tmsConnectionString" applicationName="tms" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" writeExceptionsToEventLog="true" />
      </providers>
    </membership>
    <authentication mode="Forms">
      <forms name=".ASPXFORMSAUTH" slidingExpiration="false" loginUrl="~/login.aspx" defaultUrl="~/default.aspx" path="/" protection="All" cookieless="AutoDetect" timeout="180" />
    </authentication>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>

这是默认页面的页面加载。

     protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            log.Debug("User - " + Page.User.Identity.Name);
            log.Debug("User IsAuthenticated- " + Page.User.Identity.IsAuthenticated.ToString());
            log.Debug("User AuthenticatedType- " + Page.User.Identity.AuthenticationType);

            if (Page.User.IsInRole(Tms.Constants.Roles.Administrator))
            {
                log.Debug("role: Administrator");
                ASPxMenu1.Items[0].Visible = true;
            }
            else if (Page.User.IsInRole(Tms.Constants.Roles.Manager))
            {
                log.Debug("role: Manager");
                ASPxMenu1.Items[1].Visible = true;
            }
            else {
                log.Debug("Menu not created - Role not supported");
            }
        }
    }

这是使用成员角色管理器检查用户是否在角色中的代码

    public static bool IsInRole(this IPrincipal User, Tms.Constants.Roles roletype)
    {
        string role = roletype.ToString().ToLower();
        log.DebugFormat("IsInRole role: {0}", role.ToLower());
        log.DebugFormat("IsInRole user: {0}", User.Identity.Name);

        return User.IsInRole(role.ToLower());
    }

这是日志

信息 2012-06-17 LoginPage Login1_LoggedIn - 登录:管理员
调试 2012-06-17 DefaultPage Page_Load - 用户 - 管理员
调试 2012-06-17 DefaultPage Page_Load - 用户 IsAuthenticated - True
调试 2012-06-17 DefaultPage Page_Load - User AuthenticatedType- Forms
信息 2012-06-17 用户 IsInRole - IsInRole 角色:管理员
信息 2012-06-17 用户 IsInRole - IsInRole 用户:管理员
信息 2012-06-17 用户 IsInRole - IsInRole 角色:经理
信息 2012-06-17 用户 IsInRole - IsInRole 用户:管理员
调试 2012-06-17 DefaultPage Page_Load - 未创建菜单 - 不支持角色

如果我以用户“管理员”身份登录,它会转到未创建的菜单。即使“管理员”是角色管理员。

奇怪的是,如果我使用自定义逻辑来获取用户信息,而不是会员提供程序“User.IsInRole”,DB 仍然没有返回任何值。前任:

    static public int GetUserId(string name)
    {
        log.DebugFormat("UserIdFromUsername({0})", name);

        using (var TA = new Tms.DataAccessTableAdapters.usersTableAdapter())
        {
            log.DebugFormat("connection({0})", TA.Connection.ConnectionString);

            var usertable = TA.GetDataBy_Username(name);

            log.DebugFormat("count({0})", usertable.Rows.Count.ToString());
            if (usertable.Rows.Count>0)
            {
                return usertable[0].Id;
            }
            else { return 0; }
        }
    }

它的日志

调试 2012-06-17 用户 GetUserId - UserIdFromUsername(管理员)
调试 2012-06-17 用户 GetUserId - 连接(服务器=本地主机;用户 id=root;密码=54545;持久安全信息=假;数据库=tms;端口=3306;转换零日期时间=是;允许零日期时间=真)
调试 2012-06-17 用户 GetUserId - count(0)

因此,即使该用户存在于数据库中,它也不会返回用户信息。

如果我回收 IIS 应用程序池并刷新页面,这两种情况都开始工作,我的意思是成员资格提供程序或自定义逻辑。直到我退出。再次登录,同样的问题。

应用程序级别有错误日志记录,但没有错误。来自 IIS 相关服务的系统事件日志中没有与此相关的错误或消息。

4

1 回答 1

0

这听起来像是代码中的错误,而不是配置问题(当然,您的代码可能会对导致问题的配置做出假设)。我建议您使用日志框架(例如 log4net 或滚动您自己的基于 FileStream 的简单记录器)并在页面/控制器执行期间的关键点将有关程序状态的详细信息写入记录器,然后稍后检查它们 - 这是您最接近的远程调试就可以搞定了。

最好的解决方案是安装 VS 远程调试工具并连接到您遇到问题的服务器,但如果您需要处理域间信任和身份验证问题(DCOM 是MDM 和远程调试的主要部分,可能会导致需要很长时间才能解决的问题,只是一个警告)。

更新:

感谢您发布日志。我看到您在写入日志时正在执行 .ToLower() 。我想知道区分大小写的问题是否导致 IsInRole 函数表现不佳。请记住,SQL 字符串比较不区分大小写,但 C# 区分大小写。

于 2012-06-17T20:09:39.037 回答