ASP.NET MVC - 具有 Windows 身份验证的自定义 IIdentity 或 IPrincipal
ASP.NET MVC - Custom IIdentity or IPrincipal with Windows Authentication
我正在使用 Windows 登录身份验证的内部网站。但是,我想扩展 IPrincipal 以具有其他属性。例如,我想在 @User.FirstName
或 User.AuthorizedActivity("Admin/Permissions/Edit")
中获取用户的名字(将从数据库中检索)使用活动而不是角色来隐藏某些链接等。我真的很讨厌在过去的 2 天里花时间解决这个问题,并找到了很多关于 Windows 身份验证的信息。
我的 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 现在为空的位置。我对此不知所措。任何帮助表示赞赏。我的 protected void Application_PostAuthenticateRequest(object sender, EventArgs args)
完全不正常。
我想做的就是依靠 Windows 身份验证来执行它正常执行的操作,并向 HttpContext.Current.User
添加一些额外的属性。感谢任何帮助...我不能是唯一一个尝试这样做的人。
我通常做的只是稍后请求额外的用户信息。例如,使用如下扩展方法:
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 中。
我正在使用 Windows 登录身份验证的内部网站。但是,我想扩展 IPrincipal 以具有其他属性。例如,我想在 @User.FirstName
或 User.AuthorizedActivity("Admin/Permissions/Edit")
中获取用户的名字(将从数据库中检索)使用活动而不是角色来隐藏某些链接等。我真的很讨厌在过去的 2 天里花时间解决这个问题,并找到了很多关于 Windows 身份验证的信息。
我的 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 现在为空的位置。我对此不知所措。任何帮助表示赞赏。我的 protected void Application_PostAuthenticateRequest(object sender, EventArgs args)
完全不正常。
我想做的就是依靠 Windows 身份验证来执行它正常执行的操作,并向 HttpContext.Current.User
添加一些额外的属性。感谢任何帮助...我不能是唯一一个尝试这样做的人。
我通常做的只是稍后请求额外的用户信息。例如,使用如下扩展方法:
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 中。