我为我的 ASP.net Web 应用程序使用了基于角色的自定义安全性和表单身份验证。角色、用户是从 sql server 获取的。该框架面向 4.0 版。
我已使用https://msdn.microsoft.com/en-us/library/ff649337.aspx 中的代码在登录时创建 FormsAuthenticationTicket,然后我编写了代码以在 Application_PreRequestHandlerExecute 方法中创建一个 GenericPrincipal 对象。
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if (authCookie == null) return;
FormsAuthenticationTicket authTicket;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch (Exception ex)
{
throw;
}
if (authTicket == null)
throw new Exception("");
FormsIdentity id = new FormsIdentity(authTicket);
if(HttpContext.Current.Session != null)
{
GenericPrincipal principal = new GenericPrincipal(id, new String[]{ "Manager"});
System.Threading.Thread.CurrentPrincipal = principal;
}
我已将 PrincipalPermission 属性设置为重定向页面的 page_load 方法
[PrincipalPermissionAttribute(SecurityAction.Demand, Role="Manager")]
protected void Page_Load(object sender, EventArgs e)
{
}
我在此页面中添加了一个按钮,以模拟回发。在第一次加载时没有抛出安全异常,但是如果我单击按钮,则会抛出一个安全异常,指出“请求主体权限被拒绝。”。
[SecurityException: Request for principal permission failed.]
System.Security.Permissions.PrincipalPermission.ThrowSecurityException() +3285333
System.Security.Permissions.PrincipalPermission.Demand() +419
System.Security.PermissionSet.DemandNonCAS() +117
RoleBasedSample.About.Page_Load(Object sender, EventArgs e)
但是,如果我将应用程序池设置为经典,这将无法重现。
只有当应用程序池设置为集成模式时它才会失败是有原因的吗?
GenericPrincipal principal = new GenericPrincipal(id, new String[]{ "Manager"});
HttpContext.Current.User = principal;
System.Threading.Thread.CurrentPrincipal = HttpContext.Current.User;
这解决了这个问题,不知道为什么只有当管道设置为集成并且它在没有此代码的情况下以经典方式工作时才需要这样做