SharePoint的AllowUnsafeUpdates介绍

      如果你的code通过一个”cross-site scripting”被调用,那么将不能利用code取得请求来更新sharepoint 对象。如果你知道这样做的后果,并且仍然像这样做,请读关于AllowUnsafeUpdates属性的使用。 如果你的code在正在处理一个Post请求,并且在没有做任何事情之前使用了SPUtility.ValidateFormDigest()。这将确定使这个Post请求被验证(不是一个cross-site scripting attack),在这之后你将不需要考虑AllUnSafeUpdates这个属性的设置,因为在form digest被验证之后,AllowUnsafeUpdates的默认值将是true。 微软对AllowUnsafeUpdates属性的想法是用来阻止不安全的更新的。这个属性工作的方式是如果你没有将AllowUnsafeUpdates属性设置成True,你的应用程序运行在一个HTTPContext,并且这个请求是一个Get请求,然后SharePoint将会拒绝做任何更新的。如果想更新list,web,或者SharePoint其他对象,那么首先应该创建一个Site,如果你没有将AllowUnsafeUpdates属性设置成为True那么将会得到一个异常: System.Exception: Microsoft.SharePoint.SPException: The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again. —> System.Runtime.InteropServices.COMException (0×8102006D): The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.

      拿你正在编写一个类库为例,你的code是用来调用一个Web应用程序和调用一个胖客户端,这样理解AllowUnsafeUpdates使用这个属性是很重要的。事实上如果HTTPContext.Current是Null,那么AllowUnsafeUpdates属性将永远是true。这是一种情况,在胖客户端作为一个简单的Web请求没有cross-scripting是可能的。 通常当你创建一个你自己的SPSite和SPWeb对象的时候,当你不能从SPContext中取得的时候,并且当你试着更新一些东西的时候例如:Web或List的属性,List item metadata的时候,你可能取得以上的异常。这是一个非常清晰的暗示,web的AllowUnsafeUpdate属性为false,并且这将阻止你做任何更新。将AllowUnsafeUpdate属性设置为True将很容易解决这个问题。并且有时你将AllowUnsafeUpdate属性设置为True之后仍然有这个的问题,这是有下面的原因引起的典型的问题: 如果你已经将一个Web对象的AllowUnsafeUpdate属性设置成了true,所以在设置Web的AllowUnsafeUpdate属性的时候必须要小心,确保设置的Web对象是正确的,有的时候我们取得的Web对象和我们要操作的不是相同的对象。例如:当时使用web.Lists[listId];然后你希望list.ParentWeb返回的web对象和你取得list的web是相同的。然而情况不是这样的。当你使用list.ParentWeb.Update()的时候,将不能正常工作,因为没有设置这个list.ParentWeb的AllowUnsafeUpdate属性。你设置的这个web的AllowUnsafeUpdate属性之后,但是即使这两个Web是相同的Web,也是两个不同的对象实例。通常你得到错误之后,然后使用reflector进行研究看这个两个实例是否是相同的实例。 http://community.bamboosolutions.com/blogs/bambooteamblog/archive/2008/05/15/when-allowunsafeupdates-doesn-t-work.aspx

      作者建议你可以在进行更新之前将HTTPContext.Current设置成Null, 然后重新指定他的初始保留值。这将能够保证他正常工作,但是要记得尽可能早的设置HTTPContext为Null。根据以上情况,或许SharePoint使用site.RootWeb进行更新site 级别的功能,并且这个rootweb的AllowUnsafeUpdates属性没有明确被设置成true。 有的时候在你设置AllowUnsafeUpdates为true之后,这个属性能够被重置为false。如果我们看一下这个属性是如何被管理的,那么实际上可以看出,这个属性被存储在一个和请求对象相关联的SPWeb对象中,这个Web对象实际上就是一个COM对象。 [SharePointPermission(SecurityAction.Demand, UnsafeSaveOnGet = true)] private void SetAllowUnsafeUpdates(bool allowUnsafeUpdates) { this.Request.SetIgnoreCanary(allowUnsafeUpdates); } 这实际上意味着每次的请求都被重置,这个属性也被重置为它的默认值。当一个新的web被创建的时候,当web对象被销毁的时候或者不可用SPWeb.Invalidate()方法被调用的时候,他的请求成员也被修改了。 internal void Invalidate() { if (this.m_Request != null) { if (this.m_RequestOwnedByThisWeb) { SPRequestManager.Release(this.m_Request); } this.m_Request = null; } this.m_bInited = false; this.m_bPublicPropertiesInited = false; this.m_Url = null; } 所以任何能够调用SPWeb.InValidate()方法的操作都将会reset AllUnSafeUpdate,并且将它恢复到默认值。在HTTPContext,IE WebApplications下运行的code,从一个GET Request取得的默认值都是false。

       所有使用sharepoint对象模型调用InValidate()方法的合法情况如下: (1)当SPWeb的Name和ServerRelativeUrl属性被改变之后Update方法将会被调用啊。在这种情况下,AllowUnsafeUpdate属性将会被重置,因为随着这些属性的改变Web的url将会改变,理论上随着现在只想不同的url请求对象也会改变。 (2)当任何对象实现了Isecuratble接口(SPWeb,SPList,SPListItem)将打破和这重现转换他们的继承的角色定义。也就是说在任何使用都可以调用SPRoleDefinitionCollection.BreakInheritance(),BreakRoleInheritance(), ResetRoleInheritance()或者设置HasUniquePerm的ParentWeb的AllowUnsafeUpdates属性,然后重置这个默认值,可以设置他的值为True,为以后更新其他对象做准备。 (3)在很多情况下,当你取得一些排序数据的使用,Web的AllowUnsafeUpdates属性就会被重置为False,用来阻止一些潜在的使用。同时在使用SharePoint对象模型的时候机会出现异常。并且最后,当你试着更新SharePoint对象的时候,可能取得另外一个相关的异常,异常信息如下: System.Exception: Microsoft.SharePoint.SPException: Cannot complete this action.Please try again. —> System.Runtime.InteropServices.COMException (0×80004005): Cannot complete this action.

      如果有一些更新到一个相同的对象(例如SPSite,SPWeb,SPList)这些更新将会冲突,并且SharePoint将会拒绝更新。为了从这种情况下恢复,需要创建一个SPSite和SPWeb对象的一个刷新拷贝,并且从新的拷贝中更新取得的对象。当然不要忘记将AllowUnsafeUpdates属性设置成true。简单介绍一下,如何处理AllowUnsafeUpdates属性:不要使用Get 请求从代码中更新SharePoint对象。就像你的代码是通过cross-site scripting开发的。如果你已经知道这个问题,并且仍然想进行更新操作,请参看下面的文章的第一部分,是关于如何使用AllowUnsafeUpdates属性的。如果你的程序处理一个POST请求,然后确保在做任何事情之前要调用SPUtility.ValidateFormDigest()方法。这将使这个POST请求是有效的(不是一个 cross-site scripting的攻击),并且这个操作之后你将不用考虑AllowUnsafeUpdates属性了。因为在进行Form Digest是有效的之后AllowUnsafeUpdates属性的默认值将是true。

      如果想了解更多,请读下面的信息。 正如你所看到的,当页面被提交的时候,有一个隐藏域被server设置和检查。微软的文档显示:Form Digest验证是用来帮助阻止来自用户的未知数据进行欺骗的袭击。 private void FormOnLoad(object sender, EventArgs e) { if (HttpContext.Current != null) { SPWebcontextWeb = SPControl.GetContextWeb(HttpContext.Current); if(contextWeb != null) { SPWebPartManager.RegisterOWSScript(this, contextWeb); if (this.Page.Items["FormDigestRegistered"] == null) { stringbstrUrl = SPGlobal.GetVTIRequestUrl(this.Context.Request, null).ToString(); SPStringCallback pFormCallback = new SPStringCallback(); contextWeb.Request.RenderFormDigest(bstrUrl, pFormCallback); base.ClientScript.RegisterHiddenField(“__REQUESTDIGEST”, SPHttpUtility.NoEncode(pFormCallback.StringResult)); FormDigest.RegisterDigestUpdateClientScriptBlockIfNeeded(this); this.Page.Items["FormDigestRegistered"] = true; } } } } __REQUESTDIGEST域的实际值是被OWSSVR.dll的COM对象产生的。之后 FormDigest.RegisterDigestUpdateClientScriptBlockIfNeeded()方法将会被调用。 public static void RegisterDigestUpdateClientScriptBlockIfNeeded(Page page) { doubletotalMilliseconds; if (SPContext.Current.Site.WebApplication.FormDigestSettings.Enabled) { totalMilliseconds = SPContext.Current.Site.WebApplication.FormDigestSettings.Timeout.TotalMilliseconds; if(totalMilliseconds > 2147483647.0) { totalMilliseconds = 2147483647.0; } } else { return; } int num2 = Convert.ToInt32((double)(totalMilliseconds * 0.8)); if(!page.ClientScript.IsOnSubmitStatementRegistered(typeof(FormDigest), “SPFormDigestUpdaterSubmitHandler”)) { page.ClientScript.RegisterOnSubmitStatement( typeof(FormDigest), “SPFormDigestUpdaterSubmitHandler”, “UpdateFormDigest(’” + SPEncode.ScriptEncode(SPContext.Current.Web.ServerRelativeUrl) + “‘, “+ num2.ToString(CultureInfo.InvariantCulture) + “);”); ScriptLink.Register(page, “init.js”, true, false); } }

        在以上Code中有很多有兴趣的信息。首先由server生成的Form Digest值是可以过期失效的。默认时间是30分钟。第二SPWebApplication的FormDigestSettings属性能够被用来改变每个Web应用程序Form Digest的设置。如果你想调用SPWebApplication的Update方法,这些设置将会被保存在配置数据库中。在MSDN上提供的“Enabled”属性的信息不是完全正确的。MSDN说“Enabled”属性的设置决定安全验证是否包括对所有Form页面的验证。SharePoint的代码检查和代码测试显示无论“Enabled”的值是什么,Form Digest总是被包括。False代表的意思是当Form Digest过期之后用户将不能够提交Form,并且将得到一个安全验证超时的异常。测试显示将“Enabled”属性设置False值将确实将安全验证禁用了,并且将取得到这个“The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.”异常,设置Web的AllowUnsafeUpdates属性值将是false。 public bool ValidateFormDigest() { HttpContext current = HttpContext.Current; if (current != null) { if (HttpContext.Current.Items["FormDigestValidated"] == null) { if (!this.Request.ValidateFormDigest(this.Url, null)) { return false; } current.Items["FormDigestValidated"] = true; return true; } return true; } return true; } 由于一些原因SharePoint不能总是调用ValidateFormDigest()方法。并且这就是设置AllowUnsafeUpdates属性的原因了。但是如果你自己调用这个方法,有一个更好更安全的解决方案,最好的方法是调用SPUtility.ValidateFormDigest()方法,在你的POST请求的开始。 最后如果你在SharePoint中使用自定义的ASPX页面,并且没有继承WebPartPage的话,你可以插入一个FormDigest控件,这个控件能够为你自动的添加Form Digest,并且将会阻止你cross-site scripting。并且确定调用ValidateFormDigest()方法,不会接触到AllowUnsafeUpdates属性。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SharePoint 是一种用于创建、共享和管理组织内部网站和内容的平台。它可以帮助团队协作、文档管理、数据分享和工作流程自动化。 要入门 SharePoint,以下是一些建议: 1. 了解 SharePoint 的基本概念和术语:熟悉 SharePoint 平台的基本概念,如网站、列表、库、页面和权限等。 2. 注册 SharePoint 网站:注册一个 SharePoint 网站,这是你创建和管理内容的地方。可以尝试使用 Microsoft 365 订阅或 SharePoint Online 进行注册。 3. 探索 SharePoint 网站:浏览你的 SharePoint 网站,了解其组织结构和功能。探索不同的模板和页面布局,以获取更多想法。 4. 创建列表和库:使用列表和库来组织和存储内容。例如,创建一个文档库来存储文件,或创建一个任务列表来跟踪团队的工作。 5. 学习权限管理:了解如何设置和管理用户权限,以确保只有授权人员可以访问和编辑内容。 6. 配置工作流程:利用 SharePoint 的工作流程功能来自动化业务过程。学习如何创建和配置工作流程,以提高生产力和效率。 7. 使用 SharePoint 应用程序:探索 SharePoint 应用程序,这些应用程序可以增强和扩展 SharePoint 的功能。例如,Power Automate 可以帮助你创建自定义工作流程,Power Apps 可以帮助你构建自定义应用程序。 8. 学习 SharePoint 开发:如果你具有开发经验,可以学习 SharePoint 开发来自定义和扩展 SharePoint 的功能。了解 SharePoint Framework (SPFx) 和 SharePoint Designer 等工具。 以上是入门 SharePoint 的一些建议。探索不同的功能和实践,逐步熟悉平台,并根据你的需求进行定制和配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值