ASP.NET MVC - пользовательский IIdentity или IPrincipal с аутентификацией Windows

Я работаю на сайте интрасети с аутентификацией Windows для входа в систему. Тем не менее, я хочу расширить IPrincipal, чтобы иметь другие свойства. Например, я хотел бы получить имя пользователя FirstName в @User.FirstName или User.AuthorizedActivity("Admin/Permissions/Edit") (будет извлекаться из db), используя действия вместо ролей, чтобы скрыть определенные ссылки и т.д. Я действительно имея чертовски время, выясняя это в течение последних двух дней и получая много информации, делая это с помощью Windows Authentication.

Моя настройка CustomPrincipal и BaseViewPage:

namespace Intranet_v2.Helpers
{ 
    public interface ICustomPrincipal : IPrincipal
    {
        Guid UserGuid { get; set; }
        string FirstName { get; set; }
        string LastName { get; set; }
        string FullName { get; set; }
    }

    public class CustomPrincipal : ICustomPrincipal
    {
        public IIdentity Identity { get; private set; }
        public bool IsInRole(string role) { return false; }

        public CustomPrincipal(string identity)
        {
            this.Identity = new GenericIdentity(identity);
        }

        public Guid UserGuid { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string FullName { get; set; }
    }

    public class CustomPrincipalSerializeModel
    {
        public Guid UserGuid { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string FullName { get; set; }
    }

    public class BaseController : Controller
    {
        protected virtual new CustomPrincipal User
    {   
            get { return HttpContext.User as CustomPrincipal; }
        }
    }

    public abstract class BaseViewPage : WebViewPage
    {
        public virtual new CustomPrincipal User
        {
            get { return base.User as CustomPrincipal; }
        }
    }

    public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
    {
        public virtual new CustomPrincipal User
        {
            get { return base.User as CustomPrincipal; }
        }
    }
}

Просмотров Web.Config BaseViewPage:

<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="Intranet_v2.Helpers.BaseViewPage">
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Optimization"/>
    <add namespace="System.Web.Routing" />
    <add namespace="Intranet_v2" />
  </namespaces>
</pages>

Я думаю, что моя основная проблема заключается в том, что я не знаю, что делать в protected void Application_PostAuthenticateRequest(object sender, EventArgs args) для моего файла Global.asax.cs. У меня плохая попытка настроить его здесь:

protected void Application_PostAuthenticateRequest(object sender, EventArgs args)
{
    //var application = (HttpApplication)sender;
    var context = application.Context;

    if (context.User != null || !context.User.Identity.IsAuthenticated) return;

    var formsIdentity = (FormsIdentity)context.User.Identity;

    if (formsIdentity == null) return;

    var ticket = formsIdentity.Ticket;


    JavaScriptSerializer serializer = new JavaScriptSerializer();

    CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(ticket.UserData);

    CustomPrincipal newUser = new CustomPrincipal(ticket.Name);
    newUser.UserGuid = serializeModel.UserGuid;
    newUser.FirstName = serializeModel.FirstName;
    newUser.LastName = serializeModel.LastName;
    newUser.FullName = serializeModel.FullName;

    var values = ticket.UserData.Split('|');

    var roles = values[1].Split(',');

    context.User = new GenericPrincipal(new GenericIdentity(ticket.Name, "Forms"), roles);
}

Теперь я нахожусь в точке, где @User.Name теперь null. Я нахожусь над этой головой. Любая помощь приветствуется. Мой protected void Application_PostAuthenticateRequest(object sender, EventArgs args) полностью вышел из состояния.

Все, что я хочу сделать, это полагаться на проверку подлинности Windows, чтобы делать то, что она делает нормально, и добавить несколько дополнительных свойств в HttpContext.Current.User. Любая помощь приветствуется... Я не могу быть единственным, кто пытается это сделать.

0
15 мая '17 в 15:29
источник поделиться
1 ответ

То, что я обычно делаю, просто запрашивает дополнительную информацию пользователя позже. Например, используя метод расширения, например:

public static class PrincipalExtensions
{
   private static void Initialize(string userName)
   {
      var userRecord = //Get user information from DB;

      var session = HttpContext.Current.Session;
      if (session != null)
      {
         session.Add("UserID", userRecord.ID);
         session.Add("UserEmail", userRecord.Email);
         //And so on
      }
   }

   public static long? GetUserID(this IPrincipal user)
   {
      var id = HttpContext.Current.Session["UserID"] as long?;
      if (id == null)
        Initialize();

      return (long)HttpContext.Current.Session["UserID"];
   }
}

Это примерно то, что я реализую в некоторых своих проектах; вместо того, чтобы входить в процесс входа в систему и хранить его в файле cookie, система может ленить загружать информацию и кешировать сессию, когда информация необходима.

+1
15 мая '17 в 16:39
источник

Посмотрите другие вопросы по меткам или Задайте вопрос