地下室的流星雨
看一个人是否聪明看他的答案;看一个人是否有智慧看他的问题。

2007里的权限在表面上看来与2003相比只是多了列表级的条目权限
但是在对象模型中,发生了翻天覆地的变化

首先2003里可以直接在网站或列表上给某个用户设置详细的权限
但是2007出来后,很多用户都说找不到设置详细权限的地方了,只能按照角色来设置权限
看了一下SDK,
发现2007里所有的权限都是通过角色来定义的(但是这个角色和2003的角色又完全不是一个东西,后面会说到),
不管是用户还是组,都没有和具体的权限发生直接的关系
SDK里有一张图能看的比较清楚,懒得截了,给个路径(WSS3SDK.chm):
General Reference -> Security, User, and Groups -> User, Groups and Authorization -> Authorization Object Relations

于是,在设置权限的时候,只能给用户(或组)赋予一个角色,而不能直接跨过角色去修改他的权限了
一切权限都通过角色来设置(真麻烦……)
如果要设置更加详细、自定义的权限,那么必须自己建立一个角色,然后再把这个角色分配给用户
而角色的创建只能在网站设置里完成(无法在列表、列表条目等权限设置的地方建立角色)
在网站设置->权限里,通过工具栏上的设置->管理权限级别(其实这个“权限级别”就相当于2003里“角色”的概念)来查看或修改当前网站上的角色,当然,只有当你是管理员的时候,才能看到这个操作的链接
在这里可以新建一个“权限级别”,在新建的页面里,就可以看到那些非常详细的权限了
之后,在设置网站、列表或列表条目权限的时候,就会多出我们刚刚建立出来的那个“权限级别”(角色)了

在2003的对象模型中,角色这个概念是通过SPRole来完成的
但是如果你去看2007的SDK,会发现SPRole已经被Obsolete了(我没试过使用SPRole的代码还能不能正常运行,估计没戏了……)
取而代之的是两个新的类:SPRoleDefinition和SPRoleAssignment

SPRoleDefinition用于角色(即前面所说的“权限级别”)的定义
它的几个重要的属性有:
Name:角色名称
Description:角色描述
BasePermissions:角色的权限(就是在这个地方指定详细的权限)
另外,Type属性是SPRoleType枚举类型的,这个和2003一样,枚举的条目好像也一样,说明在默认的情况下,角色还是那么几种
另外,关于权限的枚举在2003里面是SPRights,但是这个东西在2007里面同样被宣布成Obsolete的了,取而代之的是SPBasePermissions(其实内容差不太多)

SPRoleAssignment用于权限的分配,它比较简单,只有三个public的属性:
Member:把权限分配给谁
Parent:在什么东西上分配权限
RoleDefinitionBindings:分配什么权限
从最后一个东西的名字上来看,在2007里,权限的分配其实已经变成了角色的绑定
依次看一下上面这三个东西
Member是SPPrincipal类型的(它其实相当于2003里的SPMember),是SPUser和SPGroup的父类
Parent:一个实现了ISecurityxxxx接口的东东(估计2007里能分配权限的类都实现了这个接口)
RoleDefinitionBindings:可以理解为SPRoleDefinition的一个集合(虽然在对象模型上有点区别)

在2007里面
每一个能分配权限的东西(SPWeb、SPList、SPListItem等)都会有一个RoleAssignments属性,它是一个SPRoleAssignmentCollection类型的属性,用于分配权限
此外,在SPWeb里还有RoleDefinitions属性(只在SPWeb里有,也就是说角色只能定义在网站里)

举个例子,
比如我们要给一个用户(user)分配一个在列表(list)上的权限,权限使用了一个名叫“xxx”的角色
代码如下:

SPRoleAssignment ra = new SPRoleAssignment(user); SPRoleDefinition rd = web.RoleDefinitions["xxx"]; ra.RoldDefinitionBindings.Add(rd); list.RoleAssignments.Add(ra);


又比如,修改一个用户的权限:

SPRoleAssignment ra = list.RoleAssignments.GetAssignmentByPrincipal(user); SPRoleDefinition rd = web.RoleDefinitions["xxx"]; ra.RoldDefinitionBindings.Add(rd); ra.Update();

但是,如果这个列表的权限之前是继承自网站的,
那么上面的代码并不会自动的修改这种继承,反而会抛出异常
我们必须手工解除这种继承关系:

list.BreakRoleInheritance(true);


参数中true的意思是把继承下来的权限重新copy过来(如果你不改它的话,它和网站的权限还是一样的),如果是false,则使用列表模版中定义的默认权限(这个我没试过)

如果要新建一个角色的话,直接new一个SPRoleDefinition,改改它的Name、Description、BasePermissions属性,然后再加到web.RoleDefinitions里就可以了;或者在new的时候可以选择一个现有的角色copy过来,再改一改。这个代码我就不写了

此外,在权限方面还有一些其他的小改动:
在2003里,使用xxx.Permissions得到xxx(可以是SPWeb、SPList)的权限,但是在2007里Permissions属性也被废弃了
我们记得Permissions有一个非常有用的东西叫DoesUserHavePermissions来判断当前用户权限的,
在Permissions属性被废弃掉之后,这个方法移植到了SPWeb、SPList等类里
直接使用list.DoesUserHavePermissions就ok了
而且,现在这个方法不仅可以判断当前用户的权限,也可以判断指定用户的权限(通过SPUser)
另外,SPWeb、SPList及SPListItem也加入了CheckPermissions方法来判断用户权限,如果没有则丢一个异常出来,这和以前的xxx.Permissions.Demand方法是一致的 
 

///////////////////////////////////////////

In the ItemAdded-Event, you can add RoleDefinitions for each Item in the List, with the following code. The grants the person in the field Mitarbeiter as reader and in the field Vorgesetzter and Personalabteilung as Contributor. So they can also write values. The view is also filtered by these settings. 

SPListItem item = properties.ListItem;
SPWeb web = properties.OpenWeb();
SPUser user = web.EnsureUser((new SPFieldLookupValue(item["Mitarbeiter"].ToString())).LookupValue);
SPUser vorgesetzter = web.EnsureUser((new SPFieldLookupValue(item["Vorgesetzter"].ToString())).LookupValue);
SPUser personalAbteilung = web.EnsureUser((new SPFieldLookupValue(item["Personalabteilung"].ToString())).LookupValue);
SPRoleDefinition RoleDefReader = web.RoleDefinitions.GetByType(SPRoleType.Reader);
SPRoleDefinition RoleDefWriter = web.RoleDefinitions.GetByType(SPRoleType.Contributor);
SPRoleAssignment RoleAssReader = new SPRoleAssignment((SPPrincipal)user);
SPRoleAssignment RoleAssWriter = new SPRoleAssignment((SPPrincipal)vorgesetzter);
SPRoleAssignment RoleAssWriter2 = new SPRoleAssignment((SPPrincipal)personalAbteilung);
RoleAssReader.RoleDefinitionBindings.Add(RoleDefReader);
RoleAssWriter.RoleDefinitionBindings.Add(RoleDefWriter);
RoleAssWriter2.RoleDefinitionBindings.Add(RoleDefWriter);
if (!item.HasUniqueRoleAssignments)
item.BreakRoleInheritance(
false);
item.RoleAssignments.Add(RoleAssReader);
item.RoleAssignments.Add(RoleAssWriter);
item.RoleAssignments.Add(RoleAssWriter2);
item.Update();

posted on 2010-02-03 15:40  地下室的流星雨  阅读(388)  评论(0编辑  收藏  举报