在标准 ASP.NET MVC 安装模板中模拟用户
Posted
技术标签:
【中文标题】在标准 ASP.NET MVC 安装模板中模拟用户【英文标题】:Impersonate a user in a standard ASP.NET MVC installation template 【发布时间】:2017-12-14 14:51:22 【问题描述】:我已经设置了一个标准的 ASP.NET MVC 站点,并且具有正常的身份验证。我已添加角色,因此新用户将获得特定角色。
现在,我希望能够模拟用户。
冒充建议
当我四处搜索时,模仿的方式如下:
FormsAuthentication.SetAuthCookie(user.UserName, false);
默认情况下这不起作用,因为您必须做两件事:
1:
启用表单身份验证:
<system.web>
<authentication mode="Forms" />
</system.web>
2:
禁用模块:
<system.webServer>
<modules>
<!--<remove name="FormsAuthentication" />-->
</modules>
<staticContent>
挑战
但是,这样做会带来一些挑战。
-
当您模拟时,您无法注销。这很容易通过
在 LogOut 中添加以下内容:
FormsAuthentication.SignOut();
User.IsInRole(Constants.Roles.Creditor);
停止工作,所以
我们无法检查用户是否在某个角色中
怎么办?
这可能归结为我 - 显然 - 尽管尝试过,但我并没有完全理解成员资格框架。但是,您如何冒充在这里工作?
我没有明确的理由使用“表单”身份验证,而我开始走这条路的唯一原因是模拟。所以我看到我有两个明显的方向:
A) 以不同的方式实现模拟,所以我不碰我的 web.config 使用表单 B) 修复表单中的角色问题这里有什么帮助吗? :-)
【问题讨论】:
我对你的问题有点困惑。您在问题 FormsAuthentication 中引用,但您将其标记为 asp.net-membership。你实际使用的是什么? @ErikPhilips 我显然很困惑。我使用的是作为标准内置的 Identity one,我将它们混淆在一起。 你能在某处分享一个测试解决方案的 zip 文件吗? 【参考方案1】:有很多方法可以实现这一点,您真正需要做的就是将两个 Id 都获取到您的控制器并决定您希望它如何持久化(Cookie、缓存、Db 等)。
执行此操作的一种简单方法是为假冒创建声明并为此类声明添加政策。这是添加基于声明的政策的链接。
这里有一些代码可以帮助您入门:
在您的控制器中,您将需要一个执行类似操作的端点
var claims = await UserManager.GetClaimsAsync(CurrentUserId);
var claim = claims.FirstOrDefault(c => c.Type == "Impersonate");
if (claim!=null)
//You may forget to remove it or the user could end there session before you are able to
var r = await UserManager.RemoveClaimAsync(CurrentUserId, claim);
var result = await UserManager.AddClaimAsync(CurrentUserId, new Claim("Impersonate", userId));
if (!result.Succeeded)
return GetErrorResult(result);
现在使用上面的代码,我们想要用户 ID,但我们可以很容易地获得角色并将其保存在声明中。从这里你只需要决定你想如何使用这个声明。下面的链接将向您展示如何做到这一点。
https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims
请记住在完成后删除声明。
当您可能不得不冒充某个用户一段时间时,这个方法很有效。我为客户工作的一个项目需要能够一次模拟用户数周来完成其他客户的工作。
【讨论】:
【参考方案2】:如果我们需要在基本表单主体中实现IsInRole()
方法,我们需要自定义主体。
User
是一个主体对象,它包含Identities
的列表。 Default
身份不包含角色属性,所以我们需要创建自定义身份对象。
例如:
public class CustomPricipal : IPrincipal
public CustomPricipal(string username)
this.Identity = new CustomIdentity(username);
public IIdentity Identity
get;
private set;
public bool IsInRole(string role)
return this.Identity != null && ((CustomIdentity)this.Identity).Roles.Any(x => x.ToLower() == role.ToLower());
public class CustomIdentity : IIdentity
public CustomIdentity(string name)
// We can fetch the user information from database and create custom properties
this.Name = name;
this.IsAuthenticated = true;
this.AuthenticationType = "Forms";
this.Roles = new List<string>() "Admin", "SuperAdmin" ;
public string AuthenticationType
get;
private set;
public bool IsAuthenticated
get;
private set;
public string Name
get;
private set;
public List<string> Roles
get;
private set;
在global.asax.cs
public override void Init()
this.PostAuthenticateRequest += MvcApplication_PostAuthenticateRequest;
base.Init();
void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)
if (Request.IsAuthenticated)
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
Context.User = Thread.CurrentPrincipal = new CustomPricipal(authTicket.Name);
现在我们可以使用User.IsInRole("")
【讨论】:
以上是关于在标准 ASP.NET MVC 安装模板中模拟用户的主要内容,如果未能解决你的问题,请参考以下文章
在默认的 ASP.Net MVC 模板中,为啥用户每次更改时都会重新登录?
如何在 ASP.NET Core 5 MVC (.NET 5) 中获取记录的用户数据?
在哪里可以找到在 ASP .NET MVC2 中实现密码恢复的 C# 示例代码
ASP.NET MVC 4、Internet 应用程序模板、SimpleMembership - 帐户模型 - 强制执行唯一的用户名和电子邮件