gpt4 book ai didi

asp.net-mvc-3 - MVC3 Windows 身份验证覆盖 User.Identity

转载 作者:行者123 更新时间:2023-12-01 21:12:17 25 4
gpt4 key购买 nike

我正在使用 MVC3 和 MSSQL 后端构建一个 Intranet 应用程序。我的身份验证和角色(通过自定义角色提供程序)正常工作。我现在想做的是覆盖 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 以填充自定义主体。

    void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
{
if (e.Identity != null && e.Identity.IsAuthenticated)
{
CPrincipal cPrincipal = new CPrincipal(e.Identity);
HttpContext.Current.User = cPrincipal;
}
}

我在身份验证函数中有一个断点,并且正在填充主体;但是,当我在 Controller 中放置断点时,用户只是其正常的 RolePrincipal,而不是我的自定义主体。我做错了什么?

编辑:

我在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();
}
}

现在,当我放入断点时, watch 会在用户中显示以下内容:

  • 用户
    • [CSupport.Model.CPrincipal]
    • 身份

身份可访问;但是,它仍然是 WindowsIdentityCPrincipal 只能在 watch 中访问,不能直接访问。

编辑:感谢所有为此做出贡献的人。您极大地扩展了我对各个部分如何工作的理解。

我有两种工作方式,所以我想我会分享。

选项 1:覆盖 Global.asax 中的授权请求

这就是我要一起去的。

我没有使用 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);
}
}

这是对主体的覆盖

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(Roles = "super admin")]
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; // <--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}

选项 2:覆盖 AuthorizeAttribute

这是被覆盖的主体(与上面相同)

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

这里是授权属性的覆盖

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 处理个人级别的所有事务。

最佳答案

您应该重写 global.asax 中的 Application_AuthenticateRequest 方法,然后使用 Current.User 而不是 HttpContext.Current.User (不知道为什么,但有区别),而不是这样做。

那么,在 Controller 中访问它的一个简单方法是创建一个扩展方法?像这样的事情:

public static class IIdentityExtensions {
public static IMyIdentity MyIdentity(this IIdentity identity) {
return (IMyIdentity)identity;
}
}

那么你可以直接说User.Identity.IMyIdenty().FirstName。您也可以将其作为属性(property)来执行。

这是我使用的代码:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
FormsAuthenticationTicket authTicket = FormsAuthentication
.Decrypt(authCookie.Value);
var identity = new MyIdentity(authTicket.Name, "Forms",
FormsAuthenticationHelper.RetrieveAuthUserData(authTicket.UserData));
Context.User = new GenericPrincipal(identity,
DependencyResolver.Current.GetService<ISecurityHandler>()
.GetRoles(identity.Name).ToArray());
}

现在,忽略 DependencyResolver 的内容和自定义身份验证票的内容,这非常基本并且对我来说可以正常工作。

然后,在我的应用程序中,当我需要来自自定义身份的信息时,我只需使用 ((IMyIdentity)User.Identity).FirstName 或我需要的任何内容进行转换。这不是火箭科学,而且它确实有效。

关于asp.net-mvc-3 - MVC3 Windows 身份验证覆盖 User.Identity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12568426/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com