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

相關問題