我在asp.net(3.5)应用程序中使用Forms身份验证。我还使用角色来定义用户可以访问应用程序的哪些子目录。因此,我的web.config文件的相关部分如下所示:
<system.web>
<authentication mode="Forms">
<forms loginUrl="Default.aspx" path="/" protection="All" timeout="360" name="MyAppName" cookieless="UseCookies" />
</authentication>
<authorization >
<allow users="*"/>
</authorization>
</system.web>
<location path="Admin">
<system.web>
<authorization>
<allow roles="Admin"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
根据我所读到的内容,这应确保能够访问管理员目录的唯一用户将是已经过身份验证并被分配了管理员角色的用户。
用户身份验证,保存身份验证票证以及其他相关问题都可以正常工作。如果我从web.config文件中删除标签,一切正常。当我尝试强制执行只有具有Admin角色的用户应该能够访问Admin目录时,问题就出现了。
基于此MS KB article以及提供相同信息的其他网页,我已将以下代码添加到我的Global.asax文件中:
protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
if (HttpContext.Current.User != null) {
if (Request.IsAuthenticated == true) {
// Debug#1
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Context.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
// In this case, ticket.UserData = "Admin"
string[] roles = new string[1] { ticket.UserData };
FormsIdentity id = new FormsIdentity(ticket);
Context.User = new System.Security.Principal.GenericPrincipal(id, roles);
// Debug#2
}
}
}
但是,当我尝试登录时,我无法访问Admin文件夹(重定向到登录页面)。
尝试调试问题,如果我单步执行请求,如果我在上面标记为Debug#1的行上执行Context.User.IsInRole(“Admin”),则返回false。如果我在Debug#2行执行相同的语句,则它等于true。因此,至少就Global.asax而言,角色正在被正确分配。
在Global.asax之后,执行会直接跳转到Login页面(因为缺少角色会导致admin文件夹中的页面加载被拒绝)。但是,当我在登录的第一行Page_Load上执行相同的语句时,它返回false。因此,在Global.asax中的Application_AuthenticateRequest和受限目录中的WebForm的初始加载之后,角色信息正在丢失,导致身份验证失败(注意:在Page_Load中,仍然将正确的身份验证票证分配给Context.User.Id - 只有角色丢失了。)
我做错了什么,如何让它正常工作?
更新:我输入了solution below
答案 0 :(得分:5)
以下是问题和解决方案:
在开发早期,我已进入网站菜单并点击了Asp.net配置。这导致以下行添加到web.config:
<system.web>
<roleManager enabled="true" />
</system.web>
从那时起,该应用程序假设我通过Asp.net站点管理器执行角色,而不是通过FormsAuthentication角色。因此,重复失败,尽管实际的身份验证和角色逻辑设置正确。
从web.config中删除此行后,一切都运行良好。
答案 1 :(得分:0)
这只是一个随机的镜头,但是由于管理员的授权顺序,你是否被阻止了?也许您应该尝试切换拒绝所有和所有管理员。
以防它被拒绝覆盖。
(我在这里有代码示例,但他们没有出现。