在标准ASP.NET MVC安装模板中模拟用户

问题描述 投票:4回答:2

我已经设置了具有正常身份验证的标准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>

挑战

但是,这样做会带来一些挑战。

  1. 当您冒充时,您无法退出。通过在LogOut中添加以下内容可以很容易地解决这个问题:FormsAuthentication.SignOut();
  2. User.IsInRole(Constants.Roles.Creditor);停止工作,因此我们无法检查用户是否在角色中

该怎么办?

这个可能归结为我 - 显然 - 尽管尝试了,但还没有完全理解会员框架。但是,你如何冒充在这里工作?

我没有明确的理由使用“表单”身份验证,我开始使用此路径的唯一原因是模拟。所以我看到我有两个明显的方向:

  • A)以不同的方式实现模拟,因此我不会触摸我的web.config来使用表单
  • B)修复表格中的角色问题

这里有什么帮助? :-)

c# .net asp.net-mvc asp.net-mvc-5 asp.net-membership
2个回答
5
投票

有很多方法可以实现这一点,你真正需要做的就是将你的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

请记住在完成后删除声明。

当你可能不得不冒充一段时间时,这个很好用。我在客户端工作的一个项目,需要能够一次模仿用户数周,以完成其他客户的工作。


1
投票

如果我们需要在基本形式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("")

© www.soinside.com 2019 - 2024. All rights reserved.