2015-05-06 2 views
5

Я строю приложение интрасети с помощью ASP.NET MVC 5.Добавление пользовательских ролей ролей окна в ASP.NET MVC 5

Моя цель состоит в том, чтобы иметь проверку подлинности любого пользователя, сделанного Active Directory (т.е. Я использую «Аутентификацию Windows»), затем добавляю группы к любому пользователю внутри приложения (НЕ используя группы доменов).

Я нашел очень интересный кусок кода здесь:

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

Но это не работает в моем случае: когда я декорировать контроллер с [Authorize (Role = «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».

Спасибо за вашу помощь

UPDATE 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

Это работает. Я рад это найти. Просто то, что можно немного улучшить. Вместо того, чтобы устанавливать принцип в Application_PostAuthenticateRequest, используя Application_AuthenticateRequest, как указано в ссылке https://forums.asp.net/t/2124141.aspx?How+to+use+custom+Roles+using+Windows+Authentication+in+MVC+ Заявка. Пожалуйста, используйте код внутри if, если с условием HttpContext.Current.User! = Null, поскольку этот метод вызывается перед установкой Пользователя, а также после установки Пользователя. – sam113

ответ

2

Используйте этот метод, чтобы сохранить основной, поэтому он устанавливает также в теме:

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

Update: Также разрешить анонимную и испытание, если User.IsInRole это получить что-то внутри метода.

+0

спасибо. Где я должен использовать метод SetPrincipal? Какой фрагмент кода должен вызывать этот метод? –

+1

В глобальном ajax после авторизации пользователя. Вы устанавливаете идентификатор HttpContext.Current.User = (IPrincipal), но вам нужно настроить принципала. Ознакомьтесь с примерами: http://stackoverflow.com/questions/26464848/custom-authorization-in-asp-net-webapi-what-a-mess –

Смежные вопросы