SharePoint工作流开发点滴(6) -“我的任务不给你看”

一直以来都被MOSS的工作流权限问题所困扰.

我们虽然将任务分配给了某人,但事实上,所有在任务列表中有编辑权限的用户都可以编辑该任务.

而我们并不希望用户能够看到不属于自己的任务.

我曾经尝试过采用以下两种方法解决这一问题,未果.

1.更改任务列表的视图.

  1. 通常我们会把工作流任务分配给某人或者某组,所以我的想法是将任务列表的”我的任务”视图和”按我的用户组”视图合并为一个新的”所有我的任务”视图;
  2. 设置”所有我的任务”视图为默认视图;
  3. 删除其余视图;
  4. 取消用户创建视图的权限;

看起来不错,但是我连第一步都没能实现.

2.定制一个EventHandler

记得园子里的一个朋友写过一篇通过开发EventHandler来控制工作流权限的文章.

思路是为任务列表定制一个EventHandler,使任务列表在增加项目时可以自动更改该项目的权限.

通过定制EventHandler确实可以实现任务的权限分配,但是会引发另外的问题,譬如说,我的工作流中用OnTaskChanged活动来捕捉任务的变更.但是因为在任务创建之后EventHandler马上对其进行权限修改,所以导致工作流会发生一个小小的错误.

不过奇怪的是,虽然在文档库中显示该工作流发生了错误,但事实上流转还是正常的.

我一直固执的认为任务列表的权限应该是在MOSS中配置,而不应该在工作流内部做判断,后来,我终于发现我错了.

我们使用CreateTask活动来创建任务,CreateTask活动有一个HybridDictionary类型的属性叫做SpecialPermissions.

这个属性表示该任务的”特别权限”,如果指定了”特别权限”,那么创建的任务就不再继承任务列表的权限了.所以我们可以在创建任务之前为其指定这个”特别权限”.

1.新建一个全局的Contact对象用来存储分配对象

Contact assignee = default(Contact);

2.在onWorkflowActivated的Invoked事件中从初始化表单中获取assignee对象

assignee = Contact.FromName(init.contact[0].DisplayName, workflowProperties.Web);

3.在属性面板中将createTask的SpecialPermissions属性绑定到新的specialPermissions对象

4.编写createTask的MethodInvoking方法

private void createTask1_MethodInvoking(object sender, EventArgs e)
{
taskId = Guid.NewGuid();
taskProperties.AssignedTo = assignee.LoginName;
//判断分配对象是否用户
if (assignee.IsSPUser)
{
//为其添加"参与讨论"的权限.
specialPermissions.Add(assignee.LoginName, SPRoleType.Contributor);
}

//判断分配对象是否用户组
if(assignee.IsCollection)
{
try
{
SPGroup group = workflowProperties.Web.Groups[assignee.DisplayName];
//为组内每一个用户添加”参与讨论”的权限.
foreach (SPUser user in group.Users)
{
specialPermissions.Add(user.LoginName, SPRoleType.Contributor);
}
}
catch { }
}
}

因为默认的”参与讨论”权限就可以编辑工作流任务,所以为任务指定了”特别权限”之后,该任务将对不在SpecialPermissions中的用户不可见,这正是我们所需要的.

备注:原文发布于2007年8月20日,不想会被垃圾评论盯上,疯狂访问,所耗流量甚巨,遂设法变动URL重新发布。

61 Comments

  1. 嗯,很好.我��以前都是使用第一种实现的. 也有地方使用以下方法
    使用webpart(具体名称想不起来了),可将列表类型为任务的,所有分配给我的任务显示出来.
    将此webpart放到一个webpart page中,再用Iframe将page内容嵌入到我的网站主页(因为在我的网站中找不到这个部件,但在外面的网站中却有,呵呵).

  2. @zzx
    我查看了"我的任务"和"按我的用户组"的配置,尝试综合起来,却总是可耻的失败.

    @Allen Zhang
    不知道如何合并这两个视图?望赐教.

  3. szbaby

    我的流程不會做!
    大哥看了你的文章,心中有些想法.
    但是,我現在要做的是如何来控制流程。以前遗留的是用ASP来面向流程的思路来��现整个流程。
    现在我用.NET来改写。整个数据库结构,流程控制已经无法更改.请问我如何着手,因为我没有头绪。难道我就要一一在程序中判断不成。
    我思路很混乱
    能不能帮帮我?改变 IF{} ELSE {} !!!!!!

  4. @szbaby
    不着急,慢慢来.
    @AA()
    一定努力.
    @niels
    这个啊,有点复杂的说,MOSS = Microsoft Office Sharepoint Server 2007,搜一下便知如何.

  5. 其实MOSS的权限问题影响范围真的很大,比如如��对数据的控制只能精确到条目级而不是属性级,那么就有必要让给视图增加权限上的控制,我不知道为什么MOSS并没有这么做。
    还有MOSS的对象模型,也是按照权限来执行调用的,如果当前登陆的用户并不具备执行某些方法的权限的时候(比如取某个List的Item出来),是不存在例外情况的,比如我不想把数据的全部给某个用户看,但是我自己设定了条件来规定用户可以看到哪些数据,哪些不能,这样的话,除非直接读数据库,否则还是受到了权限的控制。
    总而言之,MOSS的权限只是固定了一条故事主线,没有太多的例外让我们使用,希望下一版可以有所改进。

  6. lw

    第一种方法我有办法实现,通过sharepoint designer修改任务的视图文件,可以让用户看到自己的任务和用户组的任务.

    用sharepoint designer打开列���的一个视图,找到从"Query>"开头到"</Query"结尾的中间一段代码,用下面的代码替换就可以用户看到自己的任务和用户组的任务.

    替换的代码如下:

    <Where>
    <And>
    <Or>
    <Membership Type=\"CurrentUserGroups\">
    <FieldRef Name=\"AssignedTo\"/>
    </Membership>
    <Eq>
    <FieldRef Name=\"AssignedTo\"></FieldRef>
    <Value Type=\"Integer\">
    <UserID/>
    </Value>
    </Eq>
    </Or>
    <Eq>
    <FieldRef Name=’Completed’/>
    <Value Type=’Text’>0</Value>
    </Eq>
    </And>
    </Where>

    &lt;Where&gt;&lt;And&gt;&lt;Or&gt;&lt;Membership Type="CurrentUserGroups"&gt;&lt;FieldRef Name="AssignedTo"/&gt;&lt;/Membership&gt;&lt;Eq&gt;&lt;FieldRef Name="AssignedTo"/&gt;&lt;Value Type="Integer"&gt;&lt;UserID Type="Integer"/&gt;&lt;/Value&gt;&lt;/Eq&gt;&lt;/Or&gt;&lt;Eq&gt;&lt;FieldRef Name="Completed"/&gt;&lt;Value Type="Text"&gt;0&lt;/Value&gt;&lt;/Eq&gt;&lt;/And&gt;&lt;/Where&gt;

    &lt;Where&gt;&lt;Or&gt;&lt;Membership Type="CurrentUserGroups"&gt;&lt;FieldRef Name=&quot;Author&quot;/&gt;&lt;/Membership&gt;&lt;Eq&gt;&lt;FieldRef Name=&quot;Author&quot;/&gt;&lt;Value Type="Integer"&gt;&lt;UserID Type="Integer"/&gt;&lt;/Value&gt;&lt;/Eq&gt;&lt;/Or&gt;&lt;/Where&gt;

  7. @zzx
    有很多情况,任务并不是指派给具体的某个人,而是某个用户组,比如HR,财务等等,这种情况下,用户在“按我的用户组”这个视图下就可以看到他所在用户组的任务。

  8. zzx

    谢谢笑煞天,那么“按我的用户组”视图能否在其它列表或文档库中使用呢?

  9. @zzx
    这个还真没有试过,不过文档库默认是没有此视图的吧?而且文档库中应该也不会出现某个用户组的文档吧.

  10. zzx[未注册用���]

    1.会有这样的需求:提交人所在的“用户组”成员应能看到本用户组其它成员提交的文档(如,提交人所在的用户组主管,应能看到本组成员提交的文档),但要求不能看到别的“用户组”提交的文档(如,财务组不能看到经营组)。
    2.虽然可考虑为不同用户组建立文件夹,但文件夹是静态的,达不到用户组的动态要求。
    3.既然文档库和其它除“任务”以外的列表不支持“我的用户组”视图,目前拟考虑将任务列表简化后,用附件方式提交文档,以实现第1条要求。

  11. @zzx
    我觉得你这样的需求完全可以用建文档库的方式来解决。
    确切的说,文档不象任务一样,有明确的分配对象,我们在新建或者上传一个文档的时候,并不需要指定他对谁可见,而任务不同,���们需要指定分配对象。
    为不同用户组或部门建立不同的文档库或列表,单独设置这个文档库或列表的权限为对该用户组可见,这是很容易实现的。

  12. zzx

    @笑煞天
    1. 个人在向部门提交类似工作总结的文档时,一般要求只能看到本人提交的文���(可考虑用“创建者=[本人]”的视图),但部门主管应可看到部门成员提交的所有文档(只能在其它地方另建“所有”视图了,否则个人也能看到)。
    2.同样,部门在向公司提交部门工作总结时,一般要求只能看到本部门提交的文档,但公司主管部门可看到所有部门提交的文档。但与第1种方式略有不同,需使用[我的用户组视图]。因为,提交文档时可能是部门副职,但要求部门正职或其它本组成员也能看到,否则副职出差了就没辙了。
    3.“为不同用户组或部门建立不同的文档库或列表”确实可“单独设置这个文档库或列表的权限为对该用户组可见”。但窃以为文档库或列表不宜多建,否则会给库的维护带来较大工作量(如栏、工作流等)。
    4.另外,遗憾的是,文档库不像列表那样支持“项目级权限 ”和“我的用户组”视图,因此只好考虑用上贴��第3种方法了。

  13. @zzx
    有道理,不过,为什么不把工作总结也做成工作流呢?主管干脆就不用去浏览文档库了嘛,看一些任务列表就知道有没有新的总结递上来,而且任务列表又可以方便的设置权限.
    另,可否用EventHandler对文档库新增项目的权限进行限制?

  14. zzx

    @笑煞天
    把文档做成工作流,也需要用户事先把���档上载到文档库里才成启动,这时就可能看到其它用户提交的文档了,某种情况下不满足需求。
    同时,从内容管理或知识管理的角度,到文档库中查看内容是最常用的,通过任务列表查看文档主要适用于流程处理。
    当然,咱们企业信息的开放性、公开性底,因此对权限要求过高,也算是中国特色吧。
    另外,http://www.msotec.com/topic.aspx?topicid=825,可解决:将任务列表的"我的任务"视图和"按我的用户组"视图合并为一个新的"所有我的任务"视图 之问题了?

  15. zzx

    @笑煞天
    呵呵,对不起,仔细一看就是你提出的解决方案,不好意思。

  16. 朵朵

    关于权限设定偶遇到了点问题:
    1,希望申请者指定承认者,承认者指定下一个承认者。。。所有指定在流程中的人可以查看或者说填写文档(这个应该可以做到)
    2,同时希望申请者��提交申请时可以指定个别人(没有特别固定于职位,部门,只是随意指定)有权限看到文档,但这些人不用做任何承认工作,只是被赋予权限

    请问,2的这种情况有什么好的实现方法么?

  17. @朵朵
    表单中再加一个Contact Selector,在工作流的代码中获取其中的人员,为其指定文档的权限,设置为只读.
    这样应该可以吧.

  18. 佳君

    "在属性面板中将createTask的SpecialPermissions属性绑定到新的specialPermissions对象",这句话不理解,不知道���么设SpecialPermissions属性,设什么值,新的specialPermissions对象在哪里设置,请指教,谢谢!

  19. 佳君

    以上的例子对我来说实在是太有帮助了,具体的设置上还有些弄不清���,请楼主能否分享下例子的Demo,非常感谢!

  20. 在WF的开发应用中,我遇到一个问题,希望向你请教一下,关于工作流任务的权限问题,《MOSS工作流Tips》之一 "我的任务不给你看" ,
    你在任务权��上,分析得相当不错.并用CreateTask活动来创建任务,CreateTask活动有一个HybridDictionary类型的属性叫做SpecialPermissions,来解决权限问题.这让应用变得更简单。但这里我就遇到了一个问题:
    我用CreateTask活动来创建任务时,如果没有被包函在whileActivate时,工作流的任务权限应用正常,但如果把createTask放到whileActivate里面时,SpecialPermissions就不工作了,这也使得任务的权限分配无效。请问一下��你这个问题有遇到过吗?有什么办法可以解决吗?

    这个问题我测试许久,没有结果,后来我改用另一种方法,也就是你外面说的第一种方法,自定义任务的权限,把任务当成一个item级来看待,分配权限,虽然里面我做到了任务权限分配,但又出现一个问题,那就是在工作流审批时,出现了任务锁定,无法审批工作流错误,在些,我再多问一个问题,工作流任务列表里的任务是���是不能被修改的呢?我发觉我一修改到任务列表的东西,都会出现任务锁定问题,对此问题,有什么解决的办法吗?

  21. 我用
    private void createTask1_MethodInvoking(object sender, EventArgs e)
    {
    this.TaskId1 = Guid.NewGuid(); //生成唯一任务ID
    string AssignedUser = "MOSS\\edward";
    TaskProperties1.AssignedTo = AssignedUser;

    ////为其添加"参与讨论"的权限.
    this.createTask1.SpecialPermissions = new System.Collections.Specialized.HybridDictionary();
    this.createTask1.SpecialPermissions.Add(AssignedUser, SPRoleType.Contributor);
    }
    实现不了任务权限在whileactivate跟conditionedActivityGroup,请博主给诊治一下,万分感谢~

  22. 俩个人的承诺

    @笑大哥你好,看了你的文章后,想问你一个问题:怎么样做才可以在工作流程当中自动分配审批任务给相关任务提交人的经理进行审批,这个经理人是依据提交人来进行动态分配的哦

  23. 煞天哥哥。问下,第二种方法不可见后,如果用url的话是否还是可以呢?
    是做到页面级别的权限控制还是功能级别的权限控制?
    谢谢。
    另外,如果用第一种方法的话貌似就是页面级别了吧,如果知道地址的话还是可以查看进去编辑的。

  24. @一瞬间
    视图没有权限,你说对了。
    EventHandler可以将权限细致到个人,但可能会有副作用,修改项的权限会引���项被修改的事件,如果工作流或其它EventHandler监听了此事件就会处理,但这可能不是我们想要的。

  25. MOSS123

    在狀態機工作流中,SpecialPermissions 也不可用,無效果,樓主可有解決之道?

  26. windza

    #20,
    个人在向部门提交类似工作总结的文档时,一般要求只能看到本人提交的文档(可考虑用“创建者=[本人]”的视图),但部门主管应可看到部门成员提交的所有文档(只能在其它地方另建“所有”视图了,否则个人也能看到)。

    我们是这样操作的,看是否符合你的需求:
    开启 “content approval” 功能,设定Draft Item Security 为“only users who can approve items(and the author of the item)”
    给部门主管approve的权限,其它人员只有编辑的权限

  27. 耳挖

    1.更改任务列表的视图.
    通常我们会把工作流任务分配给某人或者某组,所以我的想法是将任务列表的"我的任务"视图和"按我的用户组"视图合并为一个新的"所有我的任务"视���;
    设置"所有我的任务"视图为默认视图;
    删除其余视图;
    取消用户创建视图的权限;

    这个我试过好像可以也.

  28. 成林

    看了楼主���很多文章,给初学者帮助很大
    我这里有个问题
    看完《我的任务不给你看》我就照着做了一下,发现按楼主的步骤做了以后,我的工作流只能是第一个登录的工作流创建者才能看到,换其他任何用户也看不了,那怕是我提交给的下级审批者也看不了,反复看了楼主给我的代码,百思不得其解。为什么总是只能是第一个登录的工作流创建者才能看到任务呢?如果我要让我的下级审批者才能看到任务的话该怎么弄呢?明明是分配给了下级审批者的。想不明白,搞了好几天了,不知道楼主忙不忙,能不能帮小弟这个忙,提点建议

  29. @成林文中代码的作用就是只让assignee看到任务,而其他人看不到(除了管理员)。你可以加断点查看一下,或许你在给任务分配用户的时候,就分配错了呢。

  30. 成林

    @Windie Chai(笑煞天)
    谢谢楼主百忙之中来给我解答,我设置断点调试过了,给任务分配用户没任何问题,在工作流任务里显示的受分配任务的用户显示也没问题,但是还是那样,只有第一次登陆的用户(创建者)才能看到任务,受分配任务的用户看不到任务。
    我的sharepoint站点是这样的,通过windows认证网站(http://spworkflow/) 扩展成form认证的另一站点(http://spworkflow:8080/),测试是用的http://spworkflow:8080/的文档库,不知道是不是和这个有相关?

  31. 成林

    @Windie Chai(笑煞天)
    我测试了一下:
    部署的时候部署到80端口的网站,然后用系统用户去测试,结果是administator组的用户能看到所有的任务,但如果我把任务分配给所在User组的用户,用此用户登陆查看工作流用户,却什么也看不到。这会是怎么回事呢。

  32. 成林

    没给它分配 是不是在sharepoint站点里面也得对这个组或者用户先进行分配权限才可以的,可以只单独对一个用户分配吗?

  33. 成林

    @Windie Chai(笑煞天)
    80端口的网站只要是系统用户就等登陆,我用了一个power User组的用户,测试了一下,还是没法看到分配给他的任务。楼主说的分配权限是在80端口对应站里面对用户分配权限吗?

  34. @成林呃,当然是要在SharePoint中分配权限了,你所说的User、PowerUser该不会只是域用户吧?要现将域用户添加到SharePoint中,添加的时候可以为其分配权限。这样用户就可以用自己的帐户登陆SharePoint了。

  35. 成林

    谢谢 楼主
    我想问一下,为什么我的80端口的文档库能新建文件,而8080端口的站不能新建文件呢?

  36. 成林

    恩 谢谢 楼主~我原先不做这东西 做网站的 公司要求先弄一个workflow的demo出来 确定可行性 再去研究sharepoint 没法子 累~~

  37. 成林

    谢谢楼主 明白你的意思 我不是为了使用工作流而使用Sharepoint。而是为了用sharepoint而开发工作流 规定这样 有点无奈啊

发表评论

电子邮件地址不会被公开。 必填项已用*标注