使用托管服务标识调用 SharePoint Online。可能的?
Using a managed service identity to call into SharePoint Online. Possible?
我一直在研究 Azure 逻辑应用程序和 Azure 函数应用程序中的托管服务标识。我认为这是切片面包以来最好的事情,我正在尝试启用各种方案,其中之一是使用 MSI 获取仅限应用程序的令牌并调用 SharePoint Online。
使用逻辑应用程序,我为我的应用程序生成了一个托管服务标识,并在 SharePoint 应用程序上授予它 Sites.readwrite.All。然后使用 HTTP 操作时,我能够在使用托管服务标识作为身份验证并使用 https://.sharepoint.com 作为受众时调用 REST 端点。
然后我会更进一步并创建一个函数应用程序并遵循相同的模式。我创建了应用程序,生成了 MSI,并以与逻辑应用程序相同的方式向其添加了 Sites.readwrite.All 角色。
然后我使用下面的代码检索访问令牌并尝试生成客户端上下文:
#r "Newtonsoft.Json"
using Newtonsoft.Json;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.SharePoint.Client;
public static void Run(string input, TraceWriter log)
{
string resource = "https://<tenant>.sharepoint.com";
string apiversion = "2017-09-01";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Secret", Environment.GetEnvironmentVariable("MSI_SECRET"));
var response = client.GetAsync(String.Format("{0}/?resource={1}&api-version={2}", Environment.GetEnvironmentVariable("MSI_ENDPOINT"), resource, apiversion)).Result;
var responseContent = response.Content;
string responseString = responseContent.ReadAsStringAsync().Result.ToString();
var json = JsonConvert.DeserializeObject<dynamic>(responseString);
string accesstoken = json.access_token.ToString()
ClientContext ctx = new ClientContext("<siteurl>");
ctx.AuthenticationMode = ClientAuthenticationMode.Anonymous;
ctx.FormDigestHandlingEnabled = false;
ctx.ExecutingWebRequest += delegate (object sender, WebRequestEventArgs e){
e.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + accesstoken;
};
Web web = ctx.Web;
ctx.Load(web);
ctx.ExecuteQuery();
log.Info(web.Id.ToString());
}
}
不记名令牌已生成,但请求失败并显示 401 访问被拒绝(原因="There has been an error authenticating the request.";类别="invalid_client")
我试图将观众更改为 00000003-0000-0ff1-ce00-000000000000/.sharepoint.com@" 但这给出了不同的 401 错误,基本上说明它无法验证观众 uri。("error_description":"抛出了 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' 类型的异常。)。我还将 CSOM 调用替换为 REST 调用,模仿我使用 Logic App 所做的相同调用。
我对 oauth 2 的理解还不够好,无法理解我 运行 遇到问题的原因以及下一步该往哪里看。
为什么使用 HTTP 操作的逻辑应用程序调用有效,为什么函数应用程序无效?
有人吗?
非常基本的问题:您是否尝试过在资源字符串的末尾放置一个“/”,例如https://[tenant].sharepoint.com/ ?
这个问题也存在于其他端点,所以它可能也会干扰这里。
我一直在研究 Azure 逻辑应用程序和 Azure 函数应用程序中的托管服务标识。我认为这是切片面包以来最好的事情,我正在尝试启用各种方案,其中之一是使用 MSI 获取仅限应用程序的令牌并调用 SharePoint Online。
使用逻辑应用程序,我为我的应用程序生成了一个托管服务标识,并在 SharePoint 应用程序上授予它 Sites.readwrite.All。然后使用 HTTP 操作时,我能够在使用托管服务标识作为身份验证并使用 https://.sharepoint.com 作为受众时调用 REST 端点。
然后我会更进一步并创建一个函数应用程序并遵循相同的模式。我创建了应用程序,生成了 MSI,并以与逻辑应用程序相同的方式向其添加了 Sites.readwrite.All 角色。
然后我使用下面的代码检索访问令牌并尝试生成客户端上下文:
#r "Newtonsoft.Json"
using Newtonsoft.Json;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.SharePoint.Client;
public static void Run(string input, TraceWriter log)
{
string resource = "https://<tenant>.sharepoint.com";
string apiversion = "2017-09-01";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Secret", Environment.GetEnvironmentVariable("MSI_SECRET"));
var response = client.GetAsync(String.Format("{0}/?resource={1}&api-version={2}", Environment.GetEnvironmentVariable("MSI_ENDPOINT"), resource, apiversion)).Result;
var responseContent = response.Content;
string responseString = responseContent.ReadAsStringAsync().Result.ToString();
var json = JsonConvert.DeserializeObject<dynamic>(responseString);
string accesstoken = json.access_token.ToString()
ClientContext ctx = new ClientContext("<siteurl>");
ctx.AuthenticationMode = ClientAuthenticationMode.Anonymous;
ctx.FormDigestHandlingEnabled = false;
ctx.ExecutingWebRequest += delegate (object sender, WebRequestEventArgs e){
e.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + accesstoken;
};
Web web = ctx.Web;
ctx.Load(web);
ctx.ExecuteQuery();
log.Info(web.Id.ToString());
}
}
不记名令牌已生成,但请求失败并显示 401 访问被拒绝(原因="There has been an error authenticating the request.";类别="invalid_client")
我试图将观众更改为 00000003-0000-0ff1-ce00-000000000000/.sharepoint.com@" 但这给出了不同的 401 错误,基本上说明它无法验证观众 uri。("error_description":"抛出了 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' 类型的异常。)。我还将 CSOM 调用替换为 REST 调用,模仿我使用 Logic App 所做的相同调用。
我对 oauth 2 的理解还不够好,无法理解我 运行 遇到问题的原因以及下一步该往哪里看。
为什么使用 HTTP 操作的逻辑应用程序调用有效,为什么函数应用程序无效?
有人吗?
非常基本的问题:您是否尝试过在资源字符串的末尾放置一个“/”,例如https://[tenant].sharepoint.com/ ?
这个问题也存在于其他端点,所以它可能也会干扰这里。