2016-07-29 253 views
1

我的WPF桌面应用程序(C#)尝试通过Microsoft Graph API读取用户的Outlook电子邮件。我陷入了身份验证过程;我已经收到验证码,现在我想从Azure的访问令牌,但送出了访问令牌请求时不断收到一个HTTP 400错误代码:Azure AD OAuth2访问令牌请求错误 - 400错误请求

/**** Auth Code Retrieval ****/ 
string authCodeUrl = "https://login.microsoftonline.com/common/oauth2/authorize"; 
authCodeUrl += "?client_id" = clientId; 
authCodeUrl += "&redirect_uri=" + redirectUri; 
authCodeUrl += "&response_type=code"; 
authCodeUrl += "&resource=https%3A%2F%2Fgraph.microsoft.com%2F"; 
Process.start(authUrl); // User logs in, we get the auth code after login 
string code = "......"; // Hidden for this post 

/**** Access Token Retrieval ****/ 
string tokenUrl = "https://login.microsoftonline.com/common/oauth2/token" 
string content = "grant_type=authorization_code"; 
content += "&client_id=" + clientId; 
content += "&resource=https%3A%2F%2Fgraph.microsoft.com%2F"; 
content += "&code=" + code; 
content += "&redirect_uri=" + redirectUri; 
WebRequest request = WebRequest.Create(tokenUrl); 
request.ContentType = "application/x-www-form-urlencoded"; 
byte[] data = Encoding.UTF8.GetBytes(content); 
request.ContentLength = data.Length; 
request.Method = "POST"; 
try 
{ 
    using (Stream stream = request.GetRequestStream()) 
    { 
    stream.Write(data, 0, data.Length); 
    } 
    WebResponse response = request.GetResponse(); // This throws exception 
} 
catch (Exception error) // This catches the exception 
{ 
    Console.WriteLine(error.Message); // Outputs 400, bad request 
} 

以上是用于检索授权码的代码,然后尝试检索访问令牌。我们没有client_secret,因为秘密仅适用于Web应用程序,并且这是本机桌面WPF应用程序。我已经读过,但这不是一个问题。我在网上关注了很多教程和官方文档,主要是the official Graph authorization doc,我仍然无法弄清楚我做错了什么。任何帮助将不胜感激,谢谢。

回答

2

我用fiddler调试请求,我发现完整的错误消息:用户或管理员没有同意使用该应用程序。我搜索了一下这条消息,发现了一些堆栈文章和github问题线索,这些问题将我引向解决方案:我的请求在实际需要使用Azure租户时,基本URL中使用“common”作为租户ID我通过answer on stack获得的ID。我现在的身份验证请求的新基准URL如下所示:

https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/oauth2/authorize 

其中“xxxx -.... xxx”将被您的Azure租户ID替换!

0

如果您不使用客户端密钥,那么您需要配置您的租户以支持隐式授权流程。您可以按照this博文中的说明执行/验证配置。这需要使用Azure管理门户下载,修改应用清单并上载。

或者,也可能更好的策略是将代码切换到使用converged v2.0 authentication endpoints。它允许使用new app registration portal管理您的应用程序,并很好地支持隐式流和动态范围。您可以找到有关实际身份验证流程here的更多信息。它离你现在正在做的事情并不遥远,只需要一些小的调整。

如果此后仍然有问题,请再次联系。提琴手/网络跟踪将非常有帮助。此外,例外情况下的详细消息也会非常有帮助。

+0

您能否提供您收到的全部400条错误消息(或按照Robert的说法,完整的提琴手跟踪)。您是否确定您的应用程序已注册为本地客户端(或公共客户端)而不是Web应用程序?本地/公共客户端不需要秘密就可以为访问令牌兑换代码。 –

+0

谢谢你们的回应! Fiddler帮我解决了400错误问题 - 事实证明我的授权码已经过期。我现在正面临一个新的问题,即访问令牌响应不是包含访问令牌的JSON对象(就像我预期的那样),而是一个HTML文档。以下是提琴手跟踪:https://drive.google.com/file/d/0B9w2-YCX6qYvZmxXdERjWDJsamM/view?usp=sharing – Midas

+0

该调用似乎是/ authorize端点的POST。您应该对/ token端点执行POST以将授权码更改为访问令牌。 –