我能够通过桌面.Net项目中的MSAL检索和使用访问令牌。我可以成功检索令牌,它们在我的Graph调用中有效。
但是,尝试将访问令牌与SharePoint Online CSOM一起使用会导致显示401:未经授权。这类似于accessing sharepoint REST apis using msal throws 401(除了我使用的是C#和最新的CSOM)。
据我了解,MSFT试图将开发人员从ADAL转移到MSAL,但是令牌似乎存在一些兼容性问题。
有人能够指定必要的范围,并利用具有来自MSAL的承载授权的OAuth令牌来访问SharePoint Online吗?
答案 0 :(得分:7)
据我所知,您无法通过AAD请求带有客户端/秘密令牌的SharePoint REST API。但是它可以与证书一起使用。下面一步一步来:
由于面临同样的问题,我将在此处发布如何通过具有MSAL(OAuth v2和AAD v2终结点)的AAD应用程序设法连接到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”文件)中:
之后,您必须授权SharePoint API:
要使其正常工作,您必须分三步操作(我已对其进行了简化,但最好通过一些try / catch将操作分成方法)
对于此步骤,我强烈建议使用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();
*/
如果我什么都没错过,您应该获得一些Web /用户信息! ?
希望有帮助。
编辑(2020年11月14日):即使在我的API权限屏幕截图中,如果您尝试更新应用程序权限“ User.ReadWrite.All”,我也会添加该权限用户个人资料,它将无法使用。若要解决此问题,您必须将AAD应用程序注册为仅旧版SharePoint App主体(客户端ID /机密)。更多信息here。
感谢@laurakokkarinen和@mmsharepoint的文章对我(here和here的确有帮助)
答案 1 :(得分:0)
不确定您为什么直接使用MSAL访问SharePoint Online API。 最简单的方法应该是使用Microsoft.SharePointOnline.CSOM
var clientContext = new ClientContext(siteUrl);
clientContext.Credentials = new SharePointOnlineCredentials(userName, securedPassword);
您已完成CSOM API的使用。
但是我认为MSAL也应该可行。
请记住,您获得的令牌是为某些资源授予的。将解析的令牌复制到http://jwt.ms/并查看aud
的值
如果此字段包含https://graph.microsoft.com
,则对您https://yourtenant.sharepoint.com
无效,而您需要其他字段!
您应该可以使用Microsoft.Identity.Client
请求正确的令牌var authority = $"https://login.microsoftonline.com/{tenantId}";
var app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri(authority))
.Build();
var scopes = new[] { "https://yourtenant.sharepoint.com/.default" };
var authenticationResult = await app.AcquireTokenForClient(scopes)
.ExecuteAsync();
因此,authenticationResult.AccessToken
应该包含对SharePoint Online REST API有效的访问令牌。 (https://yourtenant.sharepoint.com/.default
意味着您请求为您的Azure AD应用程序配置的所有范围)
当您解码新的喷射令牌时,它应该像这样