模拟身份与权限提升

问题背景:某网站下存在两个列表库,用户Test1对List1具有参与讨论权限,用户Test2对List2具有参与讨论权限;而这两个用户对其他列表均只有读取权限;

问题内容:要求Test1每对List1添加一项,则List2 也增加一项相关的记录;

问题关键:SPItemEventRevicer,SPSecurity.RunWithElevatedPrivileges

 

解决:

     自定义类,继承类SPItemEventRevicer,实现 ItemAdded方法,在对List1添加完一项之后,将该项的ID保存,同时在List2中新建一项,将ID值赋予。

     在对List2进行写入操作时,由于当前HttpContext的用户是test1,所以会出现异常。所以要用到SPSecurity.RunWithElevatedPrivileges,临时以system身份运行。需要注意的是:此时要取到List2,是不能直接用当前的SPWeb或者其他对象的,因为这些对象的权限仍旧是Test1的权限,需要新建实例。

     另外,在以system身份运行中,如果觉得权限过大,可以进行其他身份模拟;即:在新建一个SPSite对象的时候,把某个用户SPUser的UserToken用户信息赋值给SPSite对象,则该SPSite对象的所有操作都以该模拟用户身份进行。

 

代码:

 

public class AskListEventHandler : SPItemEventReceiver
    
{
        
private string strSiteUrl = string.Empty;
        
private string strWebName = string.Empty;
        
private string strParentWebUrl = "/au/";//网站之下的网站
       
        
public override void ItemAdded(SPItemEventProperties properties)
        
{
            
base.ItemAdded(properties);

            
using (SPWeb web = properties.OpenWeb())
            
{
                strSiteUrl 
= web.Site.Url;
                strWebName 
= web.Name;

                SPList List1 
= web.Lists[properties.ListId];
                SPListItem list1Item 
= properties.ListItem;

                Guid m_Guid 
= Guid.NewGuid();
                list1Item[
"Index"= m_Guid;//为新建项创建一个Guid,并赋值给其Index字段
                
                list1Item.Update();
//一定要Update

                InsertIntoAnswerList(m_Guid);

            }

        }


        
private void InsertIntoAnswerList(Guid m_Guid)
        
{
            SPSecurity.RunWithElevatedPrivileges(
delegate()
            
{                
                
try
                
{
                    
using (SPSite site = new SPSite(strSiteUrl))//注意在这里一定要新建一个SPSite对象,在获取其他对象如:SPWeb
                    {
                        
using (SPWeb web = site.OpenWeb(strParentWebUrl + strWebName))
                        
{
                            SPList List2 
= web.Lists["AnswerList"];
                            SPListItem list2Item 
= answerList.Items.Add();

                            list2Item[
"Index"= m_Guid.ToString();//将Guid值赋给List2中的某个字段

                            list2Item.Update();
                        }

                    }

                }

                
catch(Exception ex)
                
{
                    
//获取异常信息,由于dll文件是要放在GAC里的,获取错误信息的方法只好通过日志察看器了。
                    EventLog urlLog = new EventLog();
                    urlLog.Source 
= "Application";

                    StringBuilder strbException 
= new StringBuilder();
                    strbException.Append(
"Message:");
                    strbException.Append(ex.Message);
                    strbException.Append(
"\r\n");
                    strbException.Append(
"Source:");
                    strbException.Append(ex.Source);
                    strbException.Append(
"\r\n");
                    strbException.Append(
"Strack:");
                    strbException.Append(ex.StackTrace);
                    strbException.Append(
"\r\n");
                    
                    urlLog.WriteEntry(strbException.ToString(), EventLogEntryType.Error);
                }

            }
);
        }
        
    }

 

在SPSecurity.RunWithElevatedPrivileges()中的代码以system身份运行,也可模拟其他用户身份。

 

          SPUser user = site.RootWeb.SiteUsers["sharepointweb\\user1"];

            //利用用户Token构造新的Site对象
          SPSite siteWithUser = new SPSite(siteUrl, user.UserToken);

此后SPSite则会以User1的身份进行运行。

 

posted @ 2008-07-25 11:44  JerryShi  阅读(334)  评论(0编辑  收藏  举报