我正在使用MVC3和MSSQL后端构建一个 内部网络 应用程序。 我已经通过自定义角色提供程序实现了身份验证和角色的功能。现在我想重写User.Identity,以允许像User.Identity.FirstName这样的项。但是我找不到任何代码可以显示如何在WindowsIdentity中完成此操作。
我尝试编写自定义提供程序:
public class CPrincipal : WindowsPrincipal
{
UserDAL userDAL = new UserDAL();
public CPrincipal(WindowsIdentity identity)
: base(identity)
{
userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
this.identity = identity;
}
public UserInfo userInfo { get; private set; }
public WindowsIdentity identity { get; private set; }
}
并覆盖 WindowsAuthentication 以填充自定义 principal。
void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
{
if (e.Identity != null && e.Identity.IsAuthenticated)
{
CPrincipal cPrincipal = new CPrincipal(e.Identity);
HttpContext.Current.User = cPrincipal;
}
}
我在身份验证函数中设置了断点,Principal(安全主体)已被填充;但是,当我在控制器中设置断点时,User只是普通的RolePrincipal,而不是我的自定义Principal。我做错了什么?
编辑:
我在global.asax中注释了上面的代码。 我使用C#覆盖了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;
}
}
我将我的主要代码调整为以下内容:
public class CPrincipal : IPrincipal
{
private UserDAL userDAL = new UserDAL();
public CPrincipal(IIdentity identity)
{
userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
this.Identity = identity;
}
public UserInfo userInfo { get; private set; }
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
throw new NotImplementedException();
}
}
现在当我设置断点时,在观察窗口中显示了以下内容:
- User
- [CSupport.Model.CPrincipal]
- Identity
“Identity”是可以访问的;然而,“CPrincipal”只能在观察窗口中访问,不能直接访问。
编辑: 感谢所有为此作出贡献的人。你们极大地扩展了我的理解。
我两种方法都试过了,所以我想分享一下。
选项1:在Global.asax中覆盖Authorize Request。
这是我选择的方法。
我没有使用Application_AuthenticateRequest,因为(根据HttpContext.Current.User is null even though Windows Authentication is on),在Windows身份验证过程中用户还没有被填充,因此我无法使用任何东西去获取用户信息。
Application_AuthorizeRequest是链中的下一个事件,发生在带入Windows身份验证之后。
protected void Application_AuthorizeRequest(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated && Roles.Enabled)
{
Context.User = new FBPrincipal(HttpContext.Current.User.Identity);
}
}
这是Principal的覆盖
public class CPrincipal : IPrincipal
{
private UserDAL userDAL = new UserDAL();
public CPrincipal(IIdentity identity)
{
userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
this.Identity = identity;
}
public UserInfo userInfo { get; private set; }
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
return userDAL.IsUserInRole(userInfo.UserName, role);
}
}
这是您访问新创建的Principal中更新信息的方法。
[Authorize(Roles = "super admin")]
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; // <--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}
选项二:重写AuthorizeAttribute
这是已重写的Principal(与上述相同)
public class CPrincipal : IPrincipal
{
private UserDAL userDAL = new UserDAL();
public CPrincipal(IIdentity identity)
{
userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
this.Identity = identity;
}
public UserInfo userInfo { get; private set; }
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
return userDAL.IsUserInRole(userInfo.UserName, role);
}
}
这里是Authorize属性的覆盖
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;
}
}
这是您更改要使用的AuthorizeAttribute并利用新信息的位置。
[CAuthorize(Roles = "super admin")] // <--
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; // <--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}
选项1全局处理所有内容,选项2针对个别情况进行处理。