简体   繁体   English

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

[英]Impersonate a user in a standard ASP.NET MVC installation template

I have setup a standard ASP.NET MVC site with normal authentication. 我已经设置了具有正常身份验证的标准ASP.NET MVC站点。 I have added roles, so new users get a specific role. 我添加了角色,因此新用户可以获得特定的角色。

Now, I want to be able to impersonate a user. 现在,我希望能够冒充用户。

Impersonating advice 假冒建议

Impersonating, when I search around, comes the following way: 当我搜索时,冒充来自以下方式:

     FormsAuthentication.SetAuthCookie(user.UserName, false);

This doesn't work by default, as you have to do two things: 这在默认情况下不起作用,因为您必须做两件事:

1: 1:

Enable forms authentication: 启用表单身份验证

 <system.web>
    <authentication mode="Forms" />
  </system.web>

2: 2:

Disable the module: 禁用模块:

<system.webServer>
    <modules>
      <!--<remove name="FormsAuthentication" />-->
    </modules>
    <staticContent>

The challenge 挑战

However, doing this leaves a couple of challenges. 但是,这样做会带来一些挑战。

  1. When you impersonate, you cannot log out. 当您冒充时,您无法退出。 This is easily fixed by adding the following in LogOut: FormsAuthentication.SignOut(); 通过在LogOut中添加以下内容可以很容易地解决这个问题: FormsAuthentication.SignOut();
  2. The User.IsInRole(Constants.Roles.Creditor); User.IsInRole(Constants.Roles.Creditor); stops working, so we cannot check if user in a role 停止工作,所以我们无法检查用户是否在角色中

What to do? 该怎么办?

This COULD boil down to me - apparently - not fully understanding the membership framework despite trying. 这个可能归结为我 - 显然 - 尽管尝试了,但还没有完全理解会员框架。 However, how do you get impersonate to work here? 但是,你如何冒充在这里工作?

I have no explicit reason to use "Forms" authentication, and the only reason I started on this path is Impersonating. 我没有明确的理由使用“表单”身份验证,我开始使用此路径的唯一原因是模拟。 So I see I have two obvious directions: 所以我看到我有两个明显的方向:

  • A) Implement impersonation in a different way, so I don't touch my web.config to use forms A)以不同的方式实现模拟,因此我不会触摸我的web.config来使用表单
  • B) Fix the role problem in forms B)修复表格中的角色问题

Any help here? 这里有什么帮助? :-) :-)

There are quite a few ways to accomplish this all you really need to do is get both the Id's to your controller and decide how you want it persisted (Cookie, Cache, Db , etc.). 有很多方法可以实现这一点,你真正需要做的就是将你的ID同时送到你的控制器并决定你想要它的持久性(Cookie,Cache,Db等)。

An easy way to do this is to create a claim for the impersonation and add a policy for those kind of claims. 一种简单的方法是为模拟创建声明并为这类声明添加策略。 Here is a link for adding claim based policies. 以下是添加基于声明的政策的链接。

Here is some code to get you started : 以下是一些可以帮助您入门的代码:

In your controllers you will want an end point that does something like this 在您的控制器中,您将需要一个类似于此的终点

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

Now with the code above we wanted the users ID, but we could have just as easily gotten there role and saved that with the claim. 现在使用上面的代码,我们需要用户ID,但我们可以轻松地获得角色并将其与声明一起保存。 From here you just need to decide how you want to use this claim. 从这里您只需要决定如何使用此声明。 The link below will show you how you can do that. 以下链接将向您展示如何做到这一点。

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims

Just remember to remove the claim after you are done. 请记住在完成后删除声明。

This one works nice when you may have to impersonate a user for sometime. 当你可能不得不冒充一段时间时,这个很好用。 One project I worked on the clients the needed to be able to impersonate users for weeks at a time to complete work for other clients. 我在客户端工作的一个项目,需要能够一次模仿用户数周,以完成其他客户的工作。

If we need to implement the IsInRole() method in basic forms principal, we need to customize the principal. 如果我们需要在基本表单主体中实现IsInRole()方法,我们需要自定义主体。

User is a principal object, which contains list of Identities . User是主要对象,其中包含Identities列表。 Default identity does not contain role property, so we need to create custom identity object. Default标识不包含角色属性,因此我们需要创建自定义标识对象。

For eg: 例如:

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

In global.asax.cs 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);
            }
        }
    }

Now we can use the User.IsInRole("") 现在我们可以使用User.IsInRole("")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM