sharepoint-online - MSAL AD 令牌对 SharePoint Online CSOM 无效
问题描述
我能够在桌面 .Net 项目中通过 MSAL 检索和使用访问令牌。我可以成功检索令牌,并且它们在我的 Graph 调用中有效。
但是,尝试将访问令牌与 SharePoint Online CSOM 一起使用会导致 401:未经授权。这类似于使用 msal throws 401 访问 sharepoint REST api(除了我使用的是 C# 和最新的 CSOM)。
据我了解,MSFT 正试图将开发人员从 ADAL 转移到 MSAL,但令牌似乎存在一些兼容性问题。
是否有人能够指定必要的范围并利用具有 MSAL 持有者授权的 OAuth 令牌来访问 SharePoint Online?
解决方案
据我所知,您不能通过 AAD 请求带有客户端/秘密令牌的 SharePoint REST API。但它适用于证书。下面一步一步来:
由于我遇到了同样的问题,我将在这里发布我如何通过带有 MSAL 的 AAD 应用程序(OAuth v2 和 AAD v2 端点)连接到 SharePoint API。它在 C# 中。
首先,我只成功了一个证书(据我所知,客户端/秘密方法不起作用)。
创建证书
出于测试目的,我使用“ New-PnPAzureCertificate ”创建了一个自签名证书,如下所示:
$secPassword = ConvertTo-SecureString -String "MyPassword" -AsPlainText -Force
$cert = New-PnPAzureCertificate -OutCert "CertSPUser.cer" -OutPfx "CertSPUser.pfx" -ValidYears 10 -CertificatePassword $secPassword -CommonName "CertSPUser" -Country "FR" -State "France"
(-Country
和-State
参数对测试无关紧要)
(它也适用于New-SelfSignedCertificate命令)
注册证书
然后,您必须在您的 AAD 应用程序(“.cer”文件)中上传证书:
配置应用程序 API 权限
之后,您必须授权 SharePoint API:
尝试通过 Daemon App (C#) 访问
NuGet 包(希望我什么都没忘记)
- Microsoft.SharePointOnline.CSOM
- Microsoft.Identity.Client
为了使事情顺利进行,您必须分 3 个步骤完成(我已经简化了它,但您最好使用一些 try/catch 将操作分成方法)
获取 Pfx 证书
对于这一步,我强烈建议使用 KeyVault(请参阅帖子底部的链接)
string certPath = System.IO.Path.GetFullPath(@"C:\PathTo\CertSPUser.pfx");
X509Certificate2 certificate = new X509Certificate2(certPath, "MyPassword", X509KeyStorageFlags.MachineKeySet);
获取令牌
string tenantId = "yourTenant.onmicrosoft.com" // Or "TenantId"
string applicationId = "IdOfYourAADApp"
IConfidentialClientApplication confApp = ConfidentialClientApplicationBuilder.Create(applicationId)
.WithAuthority($"https://login.microsoftonline.com/{tenantId}")
.WithCertificate(certificate)
.Build();
string sharePointUrl = "https://yourSharePoint.sharepoint.com" // Or "https://yourSharePoint-admin.sharepoint.com" if you want to access the User Profile REST API
var scopes = new[] { $"{sharePointUrl}/.default" };
var authenticationResult = await confApp.AcquireTokenForClient(scopes).ExecuteAsync();
string token = authenticationResult.AccessToken;
测试你的连接
ClientContext ctx = new ClientContext(sharePointUrl);
ctx.ExecutingWebRequest += (s, e) =>
{
e.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + token;
};
Web web = ctx.Web;
ctx.Load(web);
ctx.Load(web);
ctx.ExecuteQuery();
// OR if you connect to User Profile ("yourSharePoint-admin.sharepoint.com")
/*
PeopleManager peopleManager = new PeopleManager(ctx);
var personProperties = peopleManager.GetUserProfileProperties("i:0#.f|membership|employee.mail@tenant.onmicrosoft.com");
ctx.ExecuteQuery();
*/
如果我没有遗漏任何内容,您应该获得一些网络/用户信息!
希望它有所帮助。
编辑(2020 年 11 月 14 日):即使我在 API 权限的屏幕截图中添加了应用程序权限“User.ReadWrite.All”,但如果您尝试更新用户配置文件,它也不会起作用。要解决此问题,您必须将 AAD 应用程序注册为旧版 SharePoint 仅应用程序主体(客户端 ID/机密)。更多信息在这里。
感谢@laurakokkarinen和@mmsharepoint的文章对我有很大帮助(这里和这里)
推荐阅读
- python - 如何识别车牌的颜色?
- tcl - NS2:分配移动节点时出现节点移动错误
- javascript - ReferenceError: localStorage 未定义。在 Nextjs 中使用本地存储
- node.js - 如何通过 nodemailer 和 sendgrid 发送验证链接
- performance - 身份服务器 4 - GetToken 间歇性缓慢
- elasticsearch - 如何使用无痛脚本从 Elasticsearch 文档中的字段中删除特定单词
- javascript - 打字稿/反应传递道具错误'类型不存在......'
- javascript - 来自后端的 HTTP 请求和来自外部的安全 API 密钥?
- python - PyQt5 QThread 进程以退出代码 139 完成(被信号 11 中断:SIGSEGV)
- database - 数据库系统中的备份方法