在标准ASP.NET MVC安装模板

时间:2017-12-14 14:51:22

标签: c# .net asp.net-mvc asp.net-mvc-5 asp.net-membership

我已经设置了具有正常身份验证的标准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);停止工作,所以 我们无法检查角色中的用户是否
  3. 怎么做?

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

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

    • A)以不同的方式实施假冒,所以我不碰我的 web.config使用表单
    • B)修复表格中的角色问题

    这里有什么帮助吗? : - )

2 个答案:

答案 0 :(得分: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 :(得分:1)

如果我们需要在基本表单主体中实现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("")

相关问题