在我的ASP.net MVC项目中,我有(以及其他角色)主持人和用户。我想让主持人选择“以用户身份查看当前页面”。
我的方法是创建一个ActionFilterAttribute并重载OnActionExecuting& OnResult执行,然后为给定用户呈现页面。
第一个想法是与角色玩弄:
OnActionExecuting {
... //various checks, if role exist, if user want to switch
var tempRoles = Roles.getRolesForUser(user);
filterContext.HttpContext.Items["tempRole"] = tempRoles;
Roles.RemoveUserFromRoles(user, tempRoles)
Roles.AddUserToRole(user, targetRole);
}
然后
OnResultExecuted {
//if switched view
{
Roles.RemoveUserFromRole(user,targetRole)
Roles.AddUserToRoles(filterContext.HttpContext.Items["tempRole"])
}
这样可行,但在最糟糕的情况下,角色消失了,所以我宁愿不碰它们......
我的第二个想法是创建一个虚拟用户将他添加到用户角色,使用FormsAuthentication.SetAuthCookie(dummyUser,true)将主持人签名到此帐户并恢复OnResultExecuted中的所有内容,因此在最坏的情况下,用户位于dummyRole(他可以注销)和dummyUser在数据库中。
经过调试和研究后,我意识到SetAuthCookie需要一个Redirect才能生效 - 所以它不会这样工作。
问题:
答案 0 :(得分:1)
Ahoi Christian,
您可以修饰类SqlRoleProvider并将其添加到角色管理器。
请参阅示例角色提供程序实现: http://msdn.microsoft.com/en-us/library/tksy7hd7%28v=vs.100%29.aspx
装饰的SqlRoleProvider可以覆盖IsUserInRole方法,从而实现模拟功能。
编辑:我添加了以下代码:
public class MyRoleProvider : SqlRoleProvider
{
private static ConcurrentDictionary<string, string> impersonationList;
public MyRoleProvider() : base()
{
impersonationList = new ConcurrentDictionary<string, string>();
}
public static void startImpersonate(string username, string rolename)
{
impersonationList.TryAdd(username,rolename);
}
public override string[] GetRolesForUser(string username) {
if (impersonationList.ContainsKey(username))
return new string[] { impersonationList[username] };
else
return base.GetRolesForUser(username);
}
public static void stopImpersonate(string username)
{
string rolename;
impersonationList.TryRemove(username, out rolename);
}
}