今天做个小功能时,遇到个小问题。当用户在listA下添加一个item时,要对另外一个listB里的数据进行更新,而该用户对于listB只有读取权限,怎么办呢
于是翻书看看了,才发现原来MOSS有中模拟管理员权限的方法〔SPSecurity.RunWithElevatedPrivileges(delegate())},这样一来问题就解决了
1public override void ItemAdded(SPItemEventProperties properties)
2 {
3 SPWeb web = properties.OpenWeb();
4 SPListItem item = properties.ListItem;
5
6
7
8
9
10 string name = item["Name"].ToString();
11 int num = int.Parse(item["People"].ToString());
12
13
14 SPSecurity.RunWithElevatedPrivileges(delegate()
15 {
16 try
17 {
18 using (SPSite mySite = new SPSite("http://cpu"))
19 {
20 SPWeb webs = mySite.RootWeb;
21 SPList list = webs.Lists["Second"];
22
23
24
25 foreach (SPListItem newitem in list.GetItems(list.DefaultView))
26 {
27 if (newitem["Name"].ToString().Trim() == name)
28 {
29 newitem["People"] = int.Parse(newitem["People"].ToString()) - num;
30 }
31
32 newitem.Update();
33 }
34 }
35 }
36 catch(Exception ex)
37 {
38 using (StreamWriter sw = new StreamWriter(@"c:test.txt", true))
39 {
40 sw.WriteLine(ex.ToString());
41 }
42
43 }
44 }
45 );
46
47
48 }
SPSecurity.RunWithElevatedPrivileges(delegate()
{
// implementation details omitted
});
可以提升代码的运行权限,实现模拟管理员身份的功能。
在RunWithElevatedPrivileges中不要使用SPContext.Current.Web,SPContext.Current.Site,SPControl.GetContextWeb(HttpContext.Current)之类的根据当前上下文得到当前的Web或者Site,根据这些方法得到的所有对象(包括从根据这些对象得到的List,ListItem等等对象)都是以当前网站登录用户权限运作的,即使是在RunWithElevatedPrivileges其运作权限也不会是管理员。
所以,如果要真正让在RunWithElevatedPrivileges中的代码以管理员权限正常运作的话,必须重新初始化相应的对象,比如:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite mySite = new SPSite(SPContext.Current.Site.Url))
{
Response.Write(mySite.RootWeb.CurrentUser.LoginName);
}
});
以上mySite.RootWeb.CurrentUser.LoginName返回的是管理员的登录帐号。
但是如果按之前所说使用SPContext:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
Response.Write(SPContext.Current.Web.CurrentUser.LoginName);
});
这时候即使在提升权限的范围内运行,得到的也是当前网站登录帐户名,而不是管理员登录帐号
public class DemoHandler : SPItemEventReceiver //继承SharePoint数据条目事件监控类
{
public override void ItemAdded(SPItemEventProperties properties) //重载ItemAdded函数,监控新建列表条目事件
{
SPSecurity.RunWithElevatedPrivileges(delegate() //用此方法模拟管理员账户运行此事件处理程序
{
using (SPSite site = new SPSite(properties.SiteId)) //用此方法的话就不用dispose()了
{
using (SPWeb web = site.OpenWeb(properties.OpenWeb().ID)) //注意获得web的方法!!!
{
try
{
SPList list = web.Lists[properties.ListId]; //获得触发事件的列表
SPListItem item = list.Items.GetItemById(properties.ListItemId); //获得触发事件的列表条目
if (!item.HasUniqueRoleAssignments) item.BreakRoleInheritance(false); //将此条目取消权限继承,如果是“false”,则将去除所有权限,只保留系统账户,如果是“true”,则将上一级权限复制过来。
SPUser user = web.Users.GetByID(properties.CurrentUserId); //获得触发此事件的用户
SPRoleAssignment ra = new SPRoleAssignment(web.EnsureUser(user.LoginName)); //生成一个新的角色分配
ra.RoleDefinitionBindings.Add(web.RoleDefinitions["读取"]); //将此角色分配绑定“读取”权限级别
item.RoleAssignments.Add(ra); //将此新权限绑定到列表条目上
}
catch (Exception ee)
{
}
}
}
}
);
}
}