我已经设置了具有正常身份验证的标准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>
挑战
但是,这样做会带来一些挑战。
FormsAuthentication.SignOut();
User.IsInRole(Constants.Roles.Creditor);
停止工作,因此我们无法检查用户是否在角色中该怎么办?
这个可能归结为我 - 显然 - 尽管尝试了,但还没有完全理解会员框架。但是,你如何冒充在这里工作?
我没有明确的理由使用“表单”身份验证,我开始使用此路径的唯一原因是模拟。所以我看到我有两个明显的方向:
这里有什么帮助? :-)
有很多方法可以实现这一点,你真正需要做的就是将你的ID同时送到你的控制器并决定你想要它的持久性(Cookie,Cache,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
请记住在完成后删除声明。
当你可能不得不冒充一段时间时,这个很好用。我在客户端工作的一个项目,需要能够一次模仿用户数周,以完成其他客户的工作。
如果我们需要在基本形式principal中实现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("")