自从两天解决问题以来,我疯了。问题是;
我正在制作一个控制台APP,它使用全局管理员帐户(在制作新订阅时指定为管理员)与SharePoint Online交谈。我想要实现的是,我想使用CSOM为Office 365的每个网站集和子网站添加自定义操作。该代码工作正常,但在注册时由Office 365预先创建的根网站集(即https://xyz.sharepoint.com)
对于任何根网站集合的租户,它会给我以下错误;
{ " SchemaVersion":" 15.0.0.0"" LibraryVersion":" 16.0.3912.1201"" ERRORINFO" :{ " ErrorMessage":"访问被拒绝。您无权执行 这个动作或访问它 。资源"" ErrorValue":空," TraceCorrelationId":" 2a47fd9c-c07b-1000-cfb7-cdffbe3ab83a""错误码&# 34;: - 2147024891" ErrorTypeName":" System.UnauthorizedAccessException的" }," TraceCorrelationId":" 2a47fd9c-c07b-1000-cfb7-cdffbe3ab83a" }
现在用户是全局管理员。我还再次将该用户添加为网站集管理员。
同一段代码可以在其他网站集(搜索网站集,任何新制作的网站集......)上正常工作。
这是一个代码;
using (ClientContext spcollContext = new ClientContext(web.Url))
{
SecureString passWord = new SecureString();
foreach (char c in strAdminPassword.ToCharArray()) passWord.AppendChar(c);
SharePointOnlineCredentials creds = new SharePointOnlineCredentials(strAdminUser, passWord);
spcollContext.Credentials = creds;
Web currentweb = spcollContext.Web;
spcollContext.Load(currentweb);
spcollContext.ExecuteQuery();
// authCookie = creds.GetAuthenticationCookie(new Uri(web.Url));
var existingActions2 = currentweb.UserCustomActions;
spcollContext.Load(existingActions2);
spcollContext.ExecuteQuery();
var actions2 = existingActions2.ToArray();
foreach (var action in actions2)
{
if (action.Description == "CustomScriptCodeForEachsite" &&
action.Location == "ScriptLink")
{
action.DeleteObject();
spcollContext.ExecuteQuery();
}
}
var newAction2 = existingActions2.Add();
newAction2.Description = "CustomScriptCodeForEachsite";
newAction2.Location = "ScriptLink";
newAction2.ScriptBlock = scriptBlock;
newAction2.Update();
spcollContext.Load(currentweb, s => s.UserCustomActions);
spcollContext.ExecuteQuery(); // GETTING ERROR ON THIS LINE.
}
注意:上面的错误是Fiddler痕迹。
答案 0 :(得分:7)
很可能这种行为基本上是由Custom Script feature引起的 当自定义脚本功能 关闭
时,会出现此问题如何验证?
您可以使用以下控制台应用验证网站权限:
using (var ctx = GetContext(webUri, userName, password))
{
var rootWeb = ctx.Site.RootWeb;
ctx.Load(rootWeb, w => w.EffectiveBasePermissions);
ctx.ExecuteQuery();
var permissions = rootWeb.EffectiveBasePermissions;
foreach (var permission in Enum.GetValues(typeof(PermissionKind)).Cast<PermissionKind>())
{
var permissionName = Enum.GetName(typeof(PermissionKind), permission);
var hasPermission = permissions.Has(permission);
Console.WriteLine("Permission: {0}, HasPermission: {1}", permissionName, hasPermission);
}
}
,其中
public static ClientContext GetContext(Uri webUri, string userName, string password)
{
var securePassword = new SecureString();
foreach (var ch in password) securePassword.AppendChar(ch);
return new ClientContext(webUri) {Credentials = new SharePointOnlineCredentials(userName, securePassword)};
}
当SP.PermissionKind.AddAndCustomizePages设置为 False 时,添加用户自定义操作时会出现拒绝访问错误。
<强>解决方案强>
根据Turn scripting capabilities on or off:
对于自助服务创建的网站,自定义脚本将被禁用 默认
Solution: enable Allow users to run custom scripts on self-service created sites
从SharePoint管理中心启用或禁用脚本
在自定义脚本下选择:
阻止用户在个人网站上运行自定义脚本或允许 用户在个人网站上运行自定义脚本。
阻止用户在用户创建的网站上运行自定义脚本 允许用户在自助服务创建的站点上运行自定义脚本。
由于通过SharePoint Online管理中心对脚本设置所做的任何更改可能需要 24小时才能生效,因此您可以在特定网站集上启用脚本立即通过CSOM API(SharePoint Online Client Components SDK),如下所示:
public static void DisableDenyAddAndCustomizePages(ClientContext ctx, string siteUrl)
{
var tenant = new Tenant(ctx);
var siteProperties = tenant.GetSitePropertiesByUrl(siteUrl, true);
ctx.Load(siteProperties);
ctx.ExecuteQuery();
siteProperties.DenyAddAndCustomizePages = DenyAddAndCustomizePagesStatus.Disabled;
var result = siteProperties.Update();
ctx.Load(result);
ctx.ExecuteQuery();
while (!result.IsComplete)
{
Thread.Sleep(result.PollingInterval);
ctx.Load(result);
ctx.ExecuteQuery();
}
}
用法
using (var ctx = GetContext(webUri, userName, password))
{
using (var tenantAdminCtx = GetContext(tenantAdminUri, userName, password))
{
DisableDenyAddAndCustomizePages(tenantAdminCtx,webUri.ToString());
}
RegisterJQueryLibrary(ctx);
}
,其中
public static void RegisterJQueryLibrary(ClientContext context)
{
var actions = context.Site.UserCustomActions;
var action = actions.Add();
action.Location = "ScriptLink";
action.ScriptSrc = "~SiteCollection/Style Library/Scripts/jQuery/jquery.min.js";
action.Sequence = 1482;
action.Update();
context.ExecuteQuery();
}
答案 1 :(得分:2)
如果您没有Vadim所描述的CSOM时间,该页面还会链接到您可以使用的PowerShell脚本:
Set-SPOsite <SiteURL> -DenyAddAndCustomizePages 0
但请注意,SiteUrl
必须是管理员网址。如果您的租户为https://mysite.sharepoint.com,则您使用的网址为https://mysite-admin.sharepoint.com“
在我们的情况下,我们正处于部署中,当这次击中并且无法等待24小时(甚至一小时!)继续。我们的测试网站集中的一切都很好,但是当我们部署到租户根目录时,我们遇到了上述错误并且此脚本修复了它。显然,租户根目录上的功能默认关闭。
答案 2 :(得分:0)
我的第一反应是您不应该通过代码动态添加CustomAction
。也就是说,我确信你有充分的理由需要这样做。
一旦引用AllowUnsafeUpdates
,请尝试将SPWeb
上的true
标记设置为currentWeb
。在致电最终false
ExecuteQuery()
默认情况下,AllowUnsafeUpdates
为false
。它用于阻止跨站点脚本攻击。
https://msdn.microsoft.com/en-us/library/Microsoft.SharePoint.SPWeb_properties.aspx