我做错了什么?我想在我的OneDrive根目录中列出这些文件。但我总是得到一个401未经授权的。
我使用Fiddler跟踪请求,请求OAuth令牌似乎很好。但是,当我试图请求https://graph.microsoft.com/v1.0/me/drive/root/children时,我会得到未经授权的代码UnknownError的响应。
private static GraphServiceClient GetAuthenticatedGraphClient()
{
List<string> scopes = new List<string>
{
"https://graph.microsoft.com/.default",
};
var cca = ConfidentialClientApplicationBuilder.Create(CLIENT_ID)
.WithAuthority(AadAuthorityAudience.PersonalMicrosoftAccount)
.WithClientSecret(SECRET)
.Build();
GraphServiceClient graphServiceClient =
new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
{
// Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
var authResult = await cca.AcquireTokenForClient(scopes).ExecuteAsync();
// Add the access token in the Authorization header of the API
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
})
);
return graphServiceClient;
}
var drive = GraphClient.Me.Drive.Root.Children.
Request().
GetAsync();
FYI:我使用的是.NET MVC 5,我想在没有用户交互的情况下访问我的个人 onedrive。我似乎有点不知所措,我应该用什么流程来处理这个问题。
发布于 2020-12-17 02:35:41
您正在调用/me/drive/root/children
端点,因此应该使用用户令牌而不是应用程序令牌。
您使用的auth码流与:
var cca = ConfidentialClientApplicationBuilder.Create(CLIENT_ID)
.WithAuthority(AadAuthorityAudience.PersonalMicrosoftAccount)
.WithClientSecret(SECRET)
.Build();
在这里您需要添加.WithRedirectUri(redirectUri)
。参见示例这里。
这里不应该使用AcquireTokenForClient
方法,因为它需要一个带有客户凭证流的应用程序令牌。
如果您试图在.net核心MVC中调用Microsoft,请参阅此示例。
获取访问令牌:
string token = await _tokenAcquisition
.GetAccessTokenForUserAsync(GraphConstants.Scopes);
如果您的应用程序是.net MVC,请参阅此文档。
var idClient = ConfidentialClientApplicationBuilder.Create(appId)
.WithRedirectUri(redirectUri)
.WithClientSecret(appSecret)
.Build();
string message;
string debug;
try
{
string[] scopes = graphScopes.Split(' ');
var result = await idClient.AcquireTokenByAuthorizationCode(
scopes, notification.Code).ExecuteAsync();
message = "Access token retrieved.";
debug = result.AccessToken;
}
更新:
有两个场景,我们可以连接到OneDrive,而不需要任何进一步的人类互动。
GraphClient.Users["{userId or UPN}"].Drive.Root.Children
而不是GraphClient.Me.Drive.Root.Children
,因为在本例中没有用户(/me
)。
相应代码:
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantID)
.WithClientSecret(clientSecret)
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var children = await graphClient.Users["{userId or UPN}"].Drive.Root.Children
.Request()
.GetAsync();
GraphClient.Me.Drive.Root.Children
,但不希望交互登录,则可以选择使用OAuth 2.0资源所有者密码凭据的用户名/密码提供程序。这个场景还使用用户令牌而不是应用程序令牌。请注意:
Microsoft建议您不要使用ROPC流。在大多数情况下,更安全的替代方案是可用和推荐的。这个流程需要对应用程序有很高程度的信任,并且具有在其他流中不存在的风险。只有当其他更安全的流不能使用时,才应该使用此流。
在本例中,您需要添加委托权限。
相应代码:
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantID)
.Build();
var email = "{your username}";
var str = "{your password}";
var password = new SecureString();
foreach (char c in str) password.AppendChar(c);
UsernamePasswordProvider authProvider = new UsernamePasswordProvider(publicClientApplication, scopes);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var children= await graphClient.Me.Drive.Root.Children.Request()
.WithUsernamePassword(email, password)
.GetAsync();
更新2:
不幸的是,客户凭证流和ROPC(资源所有者密码凭据)流都不支持个人帐户。对于个人帐户,您必须使用我在开头提到的auth代码流,它要求您以交互的方式登录。总之,如果没有任何进一步的人类交互,就不可能访问个人Onedrive。
https://stackoverflow.com/questions/65327473
复制相似问题