5

我已阅读了许多有关此主题的问题和解答,但他们都没有帮助我解决此问题。在MVC5中无法访问自定义IPrincipal

我遇到的问题是HttpContext.Current.UserUser属性的类型是RolePrincipal而不是我的自定义主体。

这是使用Windows身份验证(仅内部网应用程序)的MVC 5 Web应用程序。我的自定义主体是WindowsPrincipal的子类,我确实实现了我自己的RoleProvider以用于授权属性标签。

当我试图通过在当前HttpContext上将其转换为我的自定义主体从IPrincipal来使用主体时,我得到一个错误,指出它的类型为RolePrincipal,显然不能将其转换为我的自定义主体。我设置我的自定义主要的Application_PostAuthenticationRequest事件:

protected void Application_PostAuthenticationRequest(object sender, EventArgs e) 
{ 
    if (User == null) 
     return; 

    using(EntityContext db = new EntityContext()) 
    { 
     var user = db.Users.SingleOrDefault(u => u.ADName.Equals(User.Identity.Name)); 
     HttpContext.Current.User = new PcsPrincipal((WindowsIdentity)User.Identity, user); 
    } 
} 

当我把在该方法中设置断点它似乎从来没有被调用,这可以解释为什么它没有得到设置为我的自定义主体。

我查看下面的问题答案,但他们一直没能解决该问题:

什么我做错误不具有主集?让我知道是否需要发布更多代码。

编辑:在WindowsAuthentication.OnAuthenticate事件中将HttpContext.Current.User设置为我的自定义主体不能解决此问题。使用该方法显示完全相同的行为。

回答

1

经过不断研究这个问题,我终于找到了答案通过另一种手段SO质疑使我的问题排序重复的:MVC3 Windows Authentication override User.Identity

下面是发表@Toby琼斯的答案(作为编辑他原来的问题),这导致我解决了我的问题,但他的回答实际上是@Erik Funkenbusch发布的两个答案的汇总& @Darin Dimitrov。回答编辑修复了一些语法&以删除一些多余的信息。

选项1:覆盖全球的授权请求。ASAX

不应该使用的Application_AuthenticateRequest事件,因为(HttpContext.Current.User为空,即使Windows身份验证上)的用户还没有被填充在Windows身份验证过程,因而没有什么,我可以用它来获取用户信息。

Application_AuthorizeRequest是在链中的下一个和所述的WindowsIdentity在使后会发生

protected void Application_AuthorizeRequest(object sender, EventArgs e) 
{ 
    if (User.Identity.IsAuthenticated && Roles.Enabled) 
    { 
     Context.User = new CustomPrincipal((WindowsIdentity)User.Identity); 
    } 
} 

选项2:重写AuthorizeAttribute

这里是授权的重写属性

public class CAuthorize : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     bool authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
      return false; 

     IIdentity user = httpContext.User.Identity; 
     CPrincipal cPrincipal = new CPrincipal(user); 
     httpContext.User = cPrincipal; 

     return true; 
    } 
} 

然后将所有AuthorizeAttributes替换为自定义版本。

选项1全局处理所有内容,而选项2使用过滤器处理更多个人级别的所有内容。

就我个人而言,我选择使用global.asax方法,因此我的自定义主体可在全局范围内使用。以下是解决我的问题的实际代码:

protected void Application_AuthorizeRequest(object source, EventArgs e) 
{ 
    if(User.Identity.IsAuthenticated && Roles.Enabled) 
    { 
     using (EntityContext db = new EntityContext()) 
     { 
      var user = db.Users.Include("Roles").SingleOrDefault(u => u.ADName.Equals(User.Identity.Name)); 
      if (user == null) 
       return; 

     PcsPrincipal principal = new PcsPrincipal((WindowsIdentity)User.Identity, user); 
      Context.User = principal; 
     } 
    }    
} 
1

应设置在WindowsAuthentication_OnAuthenticate定制事件主体时应用程序验证当前请求发生。

protected void WindowsAuthentication_OnAuthenticate(object source, WindowsAuthenticationEventArgs e) 
{ 
    using(EntityContext db = new EntityContext()) 
    { 
     var user = db.Users.SingleOrDefault(u => u.ADName.Equals(e.Identity.Name)); 
     HttpContext.Current.User = new PcsPrincipal(e.Identity, user); 
    } 
} 
+0

使用“WindowsAuthentication.OnAuthenticate”事件展示相同的行为。 – JNYRanger