2015-05-06 181 views
5

我建立使用ASP.NET MVC 5.添加自定義角色的Windows角色在ASP.NET MVC 5

我的目標是有由Active Directory所做的任何用戶的認證(即企業內部網應用我正在使用「Windows身份驗證」),然後將組添加到應用程序內部的任何用戶(不使用域組)。

,我發現了一些很有趣的一段代碼在這裏:

http://brockallen.com/2013/01/17/adding-custom-roles-to-windows-roles-in-asp-net-using-claims/

但它不是我的情況下工作:當我裝點[授權(角色=「AppRole」)控制器,即使用戶(使用聲明)與「AppRole」角色相關聯,我也無法獲得授權。

這是我的代碼:

在Global.asax.cs中

void Application_PostAuthenticateRequest() 
    { 
     if (Request.IsAuthenticated) 
     { 

      string[] roles = Utils.GetRolesForUser(User.Identity.Name); 

      var id = ClaimsPrincipal.Current.Identities.First(); 
      foreach (var role in roles) 
      { 
       //id.AddClaim(new Claim(ClaimTypes.Role, role.ToString())); 
       id.AddClaim(new Claim(ClaimTypes.Role, @"Kairos.mil\Compliance")); 
      } 


      bool pippo = User.IsInRole("Compliance"); 

      HttpContext.Current.User = (IPrincipal)id ; 

      bool pippo2 = User.IsInRole("Compliance"); 


     } 
    } 

功能GetRolesForUser如下(和工作正常):

public static string[] GetRolesForUser(string username) 
    { 
     dbOrdiniPersonaliEntities db = new dbOrdiniPersonaliEntities(); 

     string utente = StripDomain(username); 

     string[] gruppi = new string[db.vGruppiUtentis.Where(t => t.KairosLogin == utente).Count()]; 

     int i=0; 

     foreach (var gruppo in db.vGruppiUtentis.Where(t => t.KairosLogin == utente)) 
     { 

      gruppi[i]=gruppo.GruppoDes; 
      i=i++; 
     } 
     return gruppi; 
    } 

,且控制器裝飾有「標準」授權條款:

[Authorize(Roles="AppRole")] 
    public ActionResult Index(string sortOrder, string currentFilter, string DesSearchString,int? page) 
    { 
     // my code here 
    } 

有什麼想法?

在此先感謝

UPDATE

感謝@Leandro 如你所說下面的代碼

void Application_PostAuthenticateRequest() 
    { 
     if (Request.IsAuthenticated) 
     { 

      string[] roles = Utils.GetRolesForUser(User.Identity.Name); 

      ClaimsIdentity id = ClaimsPrincipal.Current.Identities.First(); 
      foreach (var role in roles) 
      { 
       //id.AddClaim(new Claim(ClaimTypes.Role, role.ToString())); 
       id.AddClaim(new Claim(ClaimTypes.Role, @"Kairos.mil\Compliance")); 
      } 

      bool pippo = User.IsInRole("Compliance"); 

      SetPrincipal((IPrincipal)id); 

      bool pippo2 = User.IsInRole("Compliance"); 


     } 
    } 

但我已經試過我收到運行時錯誤代碼達到這一點

SetPrincipal((IPrincipal)id); 

錯誤如下

無法將類型爲「System.Security.Principal.WindowsIdentity」的對象轉換爲鍵入「System.Security.Principal.IPrincipal」。

感謝您的幫助

更新2(也許解決)

嗨 展望深入SO,我發現這個資源

ASP.NET MVC and Windows Authentication with custom roles

繼答案@Xhalent,我修改了我的代碼,如下所示

protected void Application_PostAuthenticateRequest() 
    { 
     if (Request.IsAuthenticated) 
     { 
      String[] roles = Utils.GetRolesForUser(User.Identity.Name); 

      GenericPrincipal principal = new GenericPrincipal(User.Identity, roles); 

      Thread.CurrentPrincipal = HttpContext.Current.User = principal; 
     } 
    } 

它似乎現在工作正常!任何意見?有什麼缺點?非常感謝!!

+0

This works。我很高興找到這個。只是可以改進一點的東西。不要在Application_PostAuthenticateRequest中設置原則,而應使用Application_AuthenticateRequest,如鏈接中所述https://forums.asp.net/t/2124141.aspx?How+to+use+custom+Roles+using+Windows+Authentication+in+MVC+應用。請在使用條件HttpContext.Current.User!= null時使用if中的代碼,因爲在設置用戶之前以及在設置用戶之後調用此方法。 – sam113

回答

2

使用此方法來保存本金,所以它也建立在螺紋:

 private void SetPrincipal(IPrincipal principal) 
     { 
      Thread.CurrentPrincipal = principal; 
      if (HttpContext.Current != null) 
      { 
       HttpContext.Current.User = principal; 
      } 
     } 

更新:也允許匿名和測試,如果User.IsInRole是獲取方法裏面的東西。

+0

謝謝。我在哪裏必須使用SetPrincipal方法?哪一段代碼應該調用這個方法? –

+1

在授權用戶之後的全局ajax中。您設置HttpContext.Current.User =(IPrincipal)id,但您需要設置主體。看看這裏的例子:http://stackoverflow.com/questions/26464848/custom-authorization-in-asp-net-webapi-what-a-mess –