我有一个奇怪的asp.net webforms网站问题。它在vs2008中开发,具有表单身份验证和mysql后端。它在开发系统(win7)和可能的生产服务器上运行良好。
在新的2008 R2服务器上,它的行为很奇怪。当我通过登录页面登录时,它会正确地重定向到默认页面,但不会生成用户菜单。但是,如果我回收应用程序池并刷新页面,菜单会出现并且后续工作正常。如果注销和登录,再次出现同样的问题,在应用程序池回收之前没有菜单。
从日志中看,它看起来没有从DB获取值。即使数据存在。它显示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());
}
这是日志
INFO 2012-06-17 LoginPage Login1_LoggedIn - Logged In: admin DEBUG 2012-06-17 DefaultPage Page_Load - User - admin DEBUG 2012-06-17 DefaultPage Page_Load - User IsAuthenticated- True DEBUG 2012-06-17 DefaultPage Page_Load - User AuthenticatedType- Forms INFO 2012-06-17 User IsInRole - IsInRole role: administrator INFO 2012-06-17 User IsInRole - IsInRole user: admin INFO 2012-06-17 User IsInRole - IsInRole role: manager INFO 2012-06-17 User IsInRole - IsInRole user: admin DEBUG 2012-06-17 DefaultPage Page_Load - Menu not created - Role not supported
如果我以“Admin”用户身份登录,则会转到未创建的菜单。即使“管理员”是角色管理员。
奇怪的是,而不是成员资格提供者“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; }
}
}
记录
DEBUG 2012-06-17 User GetUserId - UserIdFromUsername(admin) DEBUG 2012-06-17 User GetUserId - connection(server=localhost;user id=root;password=54545;persist security info=false;database=tms;port=3306;convert zero datetime=yes;Allow Zero Datetime=True) DEBUG 2012-06-17 User GetUserId - count(0)
因此,即使该用户存在于DB中,它也不会返回用户信息。
如果我回收IIS应用程序池并只刷新页面,一切都开始适用于这两种情况,我指的是成员资格提供程序或自定义逻辑。直到我退出。再次登录,同样的问题。
应用级别存在错误记录,但没有错误。系统事件日志中没有与IIS相关的服务相关的错误或消息。
答案 0 :(得分:0)
这听起来像是代码中的错误,而不是配置问题(当然,您的代码可能会对导致问题的配置做出假设)。我建议您使用日志框架(例如log4net或滚动您自己的基于FileStream的简单记录器),并在页面/控制器执行期间在关键点将有关程序状态的详细信息写入记录器,然后再检查它们 - 它是您最接近的得到你可以得到的远程调试。
最佳解决方案是安装VS远程调试工具并连接到遇到问题的服务器,但如果您有域间信任和身份验证问题需要处理,则可能会出现问题( DCOM是MDM和远程调试的主要部分,可能会导致需要花费很长时间才能解决的问题,只是一个警告。
更新:
感谢您发布日志。在看到你的日志时,我看到你正在做.ToLower()。我想知道区分大小写的问题是否导致IsInRole函数表现不合需要。记住SQL字符串比较不区分大小写,但C#是区分大小写的。