模拟身份与权限提升

时间:2022-07-21 14:57:01

问题背景:某网站下存在两个列表库,用户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的身份进行运行。