摘要
开发SharePoint自定义工作流的时候为了获取当前的站点对象,如果利用输入参数的WorkflowContext对象来获取SPWeb对象将会导致提权不成功。
环境是非AD单服务器场景,默认用户是系统的管理员,在开发一个自定义工作流条件的时候遇到了账号在管理员账号测试下的时候都能够通过,尽管代码做了提权处理但是在具有Contributor权限的测试账号运行时一直失败,没有提权的时候会遇到Access Denied,提权后遇到工作流启动被Cancell,借这个机会Figure Out了几个事情:
1. 众所周知,使用SPSecurity.RunWithElevatedPrivileges(delegate(){})进行运行的时候是以应用程序池账号运行,可以尝试在代码中通过HttpContext.Current.User.Identity.Name来获取当前运行账号详情(未经测试,请自行确认),通过SharePoint创建新的Web应用程序的时候,SharePoint会自动为该账号添加以下权限:
引用自http://technet.microsoft.com/en-us/library/cc678863.aspx#Section3
Application pool account
The application pool account is used for application pool identity. The application pool account requires the following permission configuration settings:
The following machine-level permission is configured automatically: The application pool account is a member of WSS_WPG.
The following SQL Server and database permissions for this account are configured automatically:
The application pool accounts for Web applications are assigned to the db_owner role for the content databases.
This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database.
This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database.
2.启动工作流权限需要具有Edit Item权限,如果在通过SharePoint Designer开发的工作流中指定需要Manage List权限的则需要有相应权限
最后正常运行使用的代码:
public static bool IsAdmin(WorkflowContext context, string listId, int itemId, string userName) { SPWorkflowActivationProperties properties = new SPWorkflowActivationProperties(); bool rtnVal = false;
SPSecurity.RunWithElevatedPrivileges(delegate() { using (SPSite site = new SPSite(context.Site.Url)) {
//SPWeb web = context.Web;
SPWeb web = site.RootWeb; SPUserCollection users = web.SiteAdministrators; foreach (SPUser user in users) { if (user.LoginName == userName) { rtnVal = true; break; } } } }); return rtnVal; }
最开始通过context.Web来获取站点对象,然后通过返回的web对象来获取SiteAdministrators属性,通过Visual Studio调试时发现运行到此处会报非授权操作错误,查看web对象发现其中的currentUser属性并不是应用程序池的账号,说明即便提权过后,web仍然使用的时从context中过来的当前登录用户身份,改为创建自定义的SPSite对象后问题解决。