2016-07-29 26 views
1

Meine WPF-Desktopanwendung (C#) versucht, die Outlook-E-Mails des Benutzers über die Microsoft Graph-API zu lesen. Ich bin im Authentifizierungsprozess festgefahren. Ich habe bereits mit einem Code-Authentifizierung und jetzt versuche ich ein Zugriffstoken von Azure zu bekommen, aber halten Sie einen HTTP 400-Fehlercode erhalten, wenn die Anforderung für den Zugriffstoken aussendet:Azure AD OAuth2-Zugriffstokenanforderungsfehler - 400 ungültige Anforderung

/**** 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 
} 

Die oben ist der Code, der zum Abrufen des Authentifizierungscodes verwendet wird, gefolgt von dem Versuch, das Zugriffstoken abzurufen. Wir haben kein client_secret, da Secrets nur für Webanwendungen gelten und dies eine native Desktop-WPF-Anwendung ist. Ich habe gelesen, dass dies kein Problem ist. Ich habe viele Tutorials und offizielle Dokumente online verfolgt, hauptsächlich the official Graph authorization doc und ich kann immer noch nicht herausfinden, was ich falsch mache. Jede Hilfe würde sehr geschätzt werden, danke.

Antwort

2

Ich habe fiddler verwendet, um die Anfrage zu debuggen, und ich fand die vollständige Fehlermeldung: Der Benutzer oder Administrator hat nicht eingewilligt, die Anwendung zu verwenden. Ich habe diese Nachricht ein wenig gegooglet und einige Stack-Artikel und Github-Problem-Threads gefunden, die mich zur Lösung führten: Meine Anfrage hatte "Common" in der Basis-URL als Mandanten-ID verwendet, als ich tatsächlich meinen Azure-Mandanten verwenden musste ID, die ich durch diese answer on stack erworben habe. Meine neue Basis-URL für die Authentifizierungsanforderungen sieht nun wie:

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

wobei „xxxx -.... xxx“ würde durch Ihren Azure Mieter-ID ersetzt werden!

0

Wenn Sie kein Clientgeheimnis verwenden, müssen Sie Ihren Mandanten so konfigurieren, dass der implizite Genehmigungsfluss unterstützt wird. Sie können den Anweisungen von this Blogpost folgen, um die Konfiguration durchzuführen/zu validieren. Dazu muss das Azure-Verwaltungsportal heruntergeladen, das App-Manifest geändert und hochgeladen werden.

Alternativ und möglicherweise eine bessere Strategie ist es, den Code auf die Verwendung der converged v2.0 authentication endpoints umzustellen. Es ermöglicht die Verwaltung Ihrer Anwendung mit der new app registration portal und unterstützt implizite Flow und dynamische Bereiche. Sie finden weitere Informationen zum tatsächlichen Authentifizierungsablauf here. Es ist nicht weit von dem, was Sie gerade tun und erfordert nur ein paar kleine Verbesserungen.

Wenn Sie danach noch Probleme haben, wenden Sie sich bitte erneut an uns. Ein Fiddler/Netzwerk-Trace wäre sehr hilfreich. Auch die detaillierte Nachricht innerhalb der Ausnahme wäre sehr hilfreich.

+0

Können Sie die volle 400 Fehlermeldung, die Sie erhalten, bitte zurückgeben (oder wie Robert sagt, eine vollständige Fiddler-Ablaufverfolgung). Sind Sie sicher, dass Ihre App als nativer Client (oder öffentlicher Client) und nicht als Webanwendung registriert ist? Native/öffentliche Clients benötigen kein Geheimnis, um den Code für ein Zugriffstoken einzulösen. –

+0

Vielen Dank für beide Antworten! Fiddler hat mir geholfen, das 400-Fehler-Problem zu lösen - es stellte sich heraus, dass mein Autorisierungscode abgelaufen war. Ich stehe nun vor einem neuen Problem, bei dem die Zugriffstokenantwort kein json-Objekt ist, das das Zugriffstoken enthält (wie ich es erwartet habe), sondern ein HTML-Dokument. Hier ist der Fiddler-Trace: https://drive.google.com/file/d/0B9w2-YCX6qYvZmxXdERjWDJsamM/view?usp=sharing – Midas

+0

Dieser Aufruf scheint ein POST für den Endpunkt/authorize zu sein. Sie sollten einen POST-Vorgang für den/token-Endpunkt ausführen, um einen Autorisierungscode in ein Zugriffstoken zu ändern. –