5

Я прочитал много вопросов и ответов по этой теме, но ни один из них не помог мне решить эту проблему.Пользовательский IPrincipal не доступен в MVC5

Проблема, с которой я сталкиваюсь, заключается в том, что HttpContext.Current.User или просто User объект имеет тип RolePrincipal вместо моего основного принципала.

Это веб-приложение MVC 5, использующее проверку подлинности Windows (приложение только для интрасети). Мой пользовательский принцип является подклассом WindowsPrincipal, и я реализовал свой собственный RoleProvider для использования в тегах атрибутов Authorize.

Когда я пытаюсь использовать принципала, отбрасывая его на мой пользовательский принцип от IPrincipal в текущем HttpContext, я получаю сообщение об ошибке, указывающее, что это тип 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); 
    } 
} 

Когда я поставил точку останова в этом методе появляется никогда не дозвонились, что может объяснить, почему он не получает установлен в мой пользовательском принципал.

Я рассмотрел следующие КвА, но они не были в состоянии решить эту проблему:

  • using custom IPrincipal and IIdentity in MVC3 - Добавлена ​​регистрация обработчика событий в методе Init Global.asax.cs в. Кажется, ничего не изменилось. Также переменная _application оказалась недействительной в MVC5.
  • RoleProvider dosn't work with custom IIdentity and IPrincipal on server - Внесены изменения в файл web.config, но это вызвало различные ошибки во время выполнения с ошибками, указав, что конвейер ASP.NET настроен неправильно.

Что я делаю неправильно, чтобы не иметь Основной набор? Дайте мне знать, нужно ли размещать больше кода.

EDIT: Настройка HttpContext.Current.User для моего пользовательского принципала в событии WindowsAuthentication.OnAuthenticate не разрешает эту проблему. Точно такое же поведение проявляется с использованием этого метода.

ответ

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; 
    } 
} 

Затем замените все авторизованные атрибуты на пользовательскую версию.

Вариант 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