2008年1月20日,星期日

工作流程:只能由任务所有者执行的任务

进入Visual Studio工作流时,令许多SharePoint开发人员惊讶的是,工作流中分配的任务实际上可以由 任何 具有基本权限的SharePoint用户。在最坏的情况下,“基本权限”是指对包含工作流任务列表的SharePoint网站具有贡献权限的任何用户,显然,这可能是与用户工作流无关的大量用户。在最佳情况下,您可能绑定了权限,以便只有工作流程中涉及的用户才能使用该列表。即使这样,这仍然意味着工作流中的任何参与者都可以响应任何任务,而不仅仅是实际分配给他们的任务。在我看来,这很不好-只需要一个迷茫的用户来意外地响应别人的任务,并且您的工作流程就一片混乱。

那么我们该怎么办?

好吧,关于这方面的文章似乎并不多,但是幸运的是,最佳解决方案(AFAIK)也是最简单的解决方案。在深入研究之前,我注意到其他需要解决此问题的人采用了这样的方法,因为工作流任务只是一个列表项,我们可以执行一些代码以使用API​​来设置该列表项的权限。这是一种逻辑策略,但是很高兴在工作流框架中有专门的规定可以执行此操作-我们仍然需要编写一些代码,但是比这种方法要简单得多。关键是CreateTask活动的'SpecialPermissions'属性:



陷阱-令人困惑的是,单击该属性的省略号按钮(...)会显示一个通用的VS集合编辑器(如下所示),据我所知,该属性不能与Flat一起使用-所有控件均已禁用!




我假设这是Visual Studio 2005 Extensions for Workflow Foundation中的错误,因此我们将忽略它!但是,单击微小的蓝色“绑定属性”按钮将显示更为熟悉的“将属性绑定到实例变量”对话框-假设您尚未创建变量来存储此CreateTask的权限,则应选择“绑定到新成员”,然后创建一个字段或属性来存储权限:



这将创建一个集合对象,特别是HybridDictionary,我们可以为此任务所需的每个权限在其中添加项目。而且,我们只需要少量的代码行即可!由于我们很可能将其用于工作流中的许多(即所有)任务,因此我们有一个每次可以调用的单独方法:

私人的 虚空 setTaskPermissions(混合字典 boundDictionary, sTaskOwner)

{

    boundDictionary.Clear();

    boundDictionary.Add(sTaskOwner, SPRoleType 。贡献者);

    boundDictionary.Add(“ NT AUTHORITY \\经过身份验证的用户”, SPRoleType 。读者);

}


因此,我们传入特定于每个任务的集合,以及任务所有者的字符串用户名。然后,我们将具有“贡献者”权限的任务所有者的条目添加到字典中,为具有只读权限的所有其他用户添加一个条目。请注意,如果此任务已经发出(例如,某些东西在工作流程中被拒绝,我们又第二次回到此任务),我们还需要在添加字典之前清除字典-这样可以避免由于字典中已经存在的键而导致任何错误。


然后,调用代码如下所示:

setTaskPermissions(approveExpenseClaim_SpecialPermissions,taskProps.AssignedTo);

这将被添加到工作流程中每个CreateTask活动的代码中。第一个参数是我们之前绑定到的变量 特别权限 财产(我们正在处理的特定任务),以及 taskProps 是个 SPWorkflowTaskProperties 存放任务数据的对象。

就是这样-比使用常规API修改列表项的权限所需的代码少得多。 这样的结果是,任务所有者是唯一可以响应任务的标准用户(除了拥有完全控制权的管理员),其他所有用户都可以读取任务。不用说,如果它们与我的不同,则可以根据您的特定权限要求自定义代码。

用户体验

最后需要指出的一件事是,用户体验可能并不像您想要的那么光滑。由于我们限制了该项目的权限,因此任何单击任务但没有权限的用户都将看到标准访问被拒绝消息:



我个人认为改进是显示更友好的消息,但这将需要更多的精力和复杂性。我的观点是,对于几行代码,这种方法是在所需的工作量与保护工作流完整性之间的巨大折衷-我绝对不是一个不眠之夜的粉丝,想知道到底是什么 如果用户无意中响应了不属于他们的任务,那么就会在工作流中发生,因此对我有用。与往常一样,如果您采用其他方法来处理此问题或有其他意见,那将很高兴听到。

17条评论:

匿名 said...

克里斯,好帖子。我已经多次从客户那里得到这个确切的问题,虽然项目级权限是合理的答案,但我不知道在工作流中完成它有多么简单。谢谢你的例子!

匿名 said...

嗨,Chis,就像您的例子一样。
但是,现在我要求我要添加为贡献者的用户不能删除分配给他的任务。因此,我需要添加其他不允许用户删除该项目的权限集。有什么建议可以解决吗? THX和最诚挚的问候。

克里斯·奥'Brien 说过...

你好

I 认为 您应该寻求做的就是不要给 贡献者 权限设置给用户,但改为应用个人权限。这将使您可以灵活地授予“编辑项目”权限,而不是“删除项目”权限。您可能会创建一个自定义角色来执行此操作,因为这会将您希望应用的一组权限组合在一起。

您必须对如何编写代码进行一些研究,但是我认为这是您可以采用的方法。

HTH,

克里斯。

未知 说过...

这对个人非常有效。但是,将项目分配给组时,如果有人要求任务,然后尝试编辑任务,则会导致工作流错误。大概是因为个人名称未包含在贡献访问权限中。关于解决此问题的任何想法。我想摆脱Claim Task函数,但是不知道怎么做。

克里斯·奥'Brien 说过...

嗨,布拉德,

嗯,很有趣-但是您不能简单地使用SPRoleType.Contributor访问权限而不是个人将组添加到字典中吗?

干杯,

克里斯。

贾巴 说过...

这个例子很好用,但是如何确定只有一个用户编辑任务?我尚未在工作流中使用的SP Task处理中找到锁定/解锁机制。

再次感谢。

克里斯·奥'Brien 说过...

贾巴

自考虑以来已经有一段时间了,但是我敢肯定,这种情况在某些地方会有所保护。可能是因为任务是一个列表项目,需要签入/签出。失败的原因可能是工作流程任务屏幕提供了解决冲突的方法(例如,诸如``任务已被修改,您要覆盖还是放弃所做的更改?''之类的消息)。

建议进行一些测试以确保确定。

HTH,

克里斯。

匿名 said...

谢谢你的提示。这很有帮助

阿纳斯·布希(Anas Boushie) 说过...

我可以为用户组设置权限吗,我已经创建了组并将其命名为HR Group,我向其中添加了users(usera,userb)。
当usera和userb都尝试打开任务时,得到的Error“值未超出预期范围。但是当我将任务分配给一个用户时,一切正常

乔瑟斯·奈尔 said...

您可以将一个组添加到字典中,并且效果很好...(至少它对我有用:))

匿名 said...

I'我有一个新的Sharepoint开发箱'我正在努力,我注意到我不再有蓝色的小链接"绑定选定的属性"在“属性”窗口下。有谁知道我怎么能让它再次出现。我可以'如果没有,请设置SpecialPermissions属性。谢谢。

克里斯·奥'Brien 说过...

@匿名,

可能是该属性已经绑定到某些东西了吗?建议通过在代码中进行搜索来进行检查。

HTH,

克里斯。

吉妮·阿图尔·沙玛(Ginni Atul Sharma) 说过...

克里斯,你好

这是一个不错的帖子。我必须感激。我也遇到了这个问题,并想出了一个解决方案,与此相去甚远。我想分享。

我使用SharePoint Designer来完成此任务。在那边,我下载了一个称为授予权限的活动(将权限分配给任何用户)。然后,我只给该任务列表的所有用户一个读取权限,并创建了一个小的工作流程,每当创建任何项目时,授予权限活动都将向"Assigned To"人。这样,已分配任务的人员只能拥有“贡献”权限。

问候
金妮

匿名 said...

这是一个不错的帖子,但事实并非如此'不适合团体。可以在字典中添加组名,但这样做不会't为组分配权限。有谁知道为小组这样做的方法吗?

米娜 说过...

克里斯你好
感谢这篇文章

麦克雷尔 said...

如果要限制对一个或多个组的访问,可以使用内置的“角色”功能。参考第6章:Khosravi的专业Microsoft 的SharePoint 2007工作流编程。
1)对于每个任务,将Roles属性设置为唯一字段。
2)在“激活的工作流”集中,哪个组可以执行任务:
WorkflowRole burnPermitApproversWorkflowRole = SPWorkflowWorkflowRoleCreator.GetWorkflowRoleForGroups(
网站Config.GetAppSetting("BurnPermitApproversGroupName"));
//为事件添加角色'的角色集合,以允许具有此角色的用户
//执行onTaskChanged_InitialReview事件
onTaskChanged_InitialReview_Roles.Add(burnPermitApproversWorkflowRole);

-马塞尔·B

匿名 said...

非常好 ;-)

对我来说效果很好,非常感谢