使用全局管理员帐户访问被拒绝的 office 365 / SharePoint 在线
Access denied office 365 / SharePoint online with Global Admin account
两天解决一个问题我快疯了。问题是;
我正在制作一个控制台应用程序,它使用全局管理员帐户(在进行新订阅时被指定为管理员)与 SharePoint Online 对话。我想要实现的是,我想使用 CSOM 向 Office 365 的每个网站集和子网站添加自定义操作。该代码工作正常,但在注册时由 Office 365 预先创建的根网站集除外(即https://xyz.sharepoint.com)
对于根网站集的任何租户,它给我以下错误;
{
"SchemaVersion":"15.0.0.0","LibraryVersion":"16.0.3912.1201","ErrorInfo":{
"ErrorMessage":"Access denied. You do not have permission to perform
this action or access this
resource.","ErrorValue":null,"TraceCorrelationId":"2a47fd9c-c07b-1000-cfb7-cdffbe3ab83a","ErrorCode":-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痕迹。
我的第一反应是您不应该在代码中即时添加 CustomAction
。也就是说,我相信您有充分的理由需要这样做。
一旦引用 currentWeb
,请尝试将 SPWeb
上的 AllowUnsafeUpdates
标志设置为 true
。确保在调用最终 ExecuteQuery()
后也将其设置回 false
默认情况下,AllowUnsafeUpdates
为 false
。它用于阻止跨站点脚本攻击。
https://msdn.microsoft.com/en-us/library/Microsoft.SharePoint.SPWeb_properties.aspx
这种行为很可能是由 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:
For self-service created sites, custom scripting is disabled by
default
Solution: enable Allow users to run custom scripts on self-service created sites
从 SharePoint 管理中心启用或禁用脚本
- 使用工作或学校帐户登录 Office 365。
- 转到 SharePoint 管理中心。
- Select 设置。
在自定义脚本下选择:
阻止用户运行在个人网站上使用自定义脚本或允许
用户 运行 在个人网站上自定义脚本。
阻止用户运行在用户创建的网站上使用自定义脚本或
允许用户在自助创建的网站上运行自定义脚本。
- Select 好的。更改需要 大约 24 小时
效果。
由于通过 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();
}
如果您没有时间按照 Vadim 的描述使用 CSOM,该页面还链接到您可以使用的 powershell 脚本:
Set-SPOsite <SiteURL> -DenyAddAndCustomizePages 0
但请注意 SiteUrl
需要成为管理员 url。如果您的租户是 https://mysite.sharepoint.com, the url you use is https://mysite-admin.sharepoint.com"
在我们的案例中,当这个问题发生时我们正在进行部署,无法等待 24 小时(甚至一小时!)才能继续。在我们的测试站点集合中一切都很好,但是当我们部署到租户根目录时,我们遇到了上述错误并且此脚本修复了它。显然,该功能在租户根目录下默认处于关闭状态。
两天解决一个问题我快疯了。问题是;
我正在制作一个控制台应用程序,它使用全局管理员帐户(在进行新订阅时被指定为管理员)与 SharePoint Online 对话。我想要实现的是,我想使用 CSOM 向 Office 365 的每个网站集和子网站添加自定义操作。该代码工作正常,但在注册时由 Office 365 预先创建的根网站集除外(即https://xyz.sharepoint.com)
对于根网站集的任何租户,它给我以下错误;
{ "SchemaVersion":"15.0.0.0","LibraryVersion":"16.0.3912.1201","ErrorInfo":{ "ErrorMessage":"Access denied. You do not have permission to perform this action or access this resource.","ErrorValue":null,"TraceCorrelationId":"2a47fd9c-c07b-1000-cfb7-cdffbe3ab83a","ErrorCode":-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痕迹。
我的第一反应是您不应该在代码中即时添加 CustomAction
。也就是说,我相信您有充分的理由需要这样做。
一旦引用 currentWeb
,请尝试将 SPWeb
上的 AllowUnsafeUpdates
标志设置为 true
。确保在调用最终 ExecuteQuery()
false
默认情况下,AllowUnsafeUpdates
为 false
。它用于阻止跨站点脚本攻击。
https://msdn.microsoft.com/en-us/library/Microsoft.SharePoint.SPWeb_properties.aspx
这种行为很可能是由 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:
For self-service created sites, custom scripting is disabled by default
Solution: enable Allow users to run custom scripts on self-service created sites
从 SharePoint 管理中心启用或禁用脚本
- 使用工作或学校帐户登录 Office 365。
- 转到 SharePoint 管理中心。
- Select 设置。
在自定义脚本下选择:
阻止用户运行在个人网站上使用自定义脚本或允许 用户 运行 在个人网站上自定义脚本。
阻止用户运行在用户创建的网站上使用自定义脚本或 允许用户在自助创建的网站上运行自定义脚本。
- Select 好的。更改需要 大约 24 小时 效果。
由于通过 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();
}
如果您没有时间按照 Vadim 的描述使用 CSOM,该页面还链接到您可以使用的 powershell 脚本:
Set-SPOsite <SiteURL> -DenyAddAndCustomizePages 0
但请注意 SiteUrl
需要成为管理员 url。如果您的租户是 https://mysite.sharepoint.com, the url you use is https://mysite-admin.sharepoint.com"
在我们的案例中,当这个问题发生时我们正在进行部署,无法等待 24 小时(甚至一小时!)才能继续。在我们的测试站点集合中一切都很好,但是当我们部署到租户根目录时,我们遇到了上述错误并且此脚本修复了它。显然,该功能在租户根目录下默认处于关闭状态。