0

I want to get outlook contacts into my ionic/angular web app. I'm trying to get the access token for microsoft api using implicit flow in order to access user's contacts. I've tried the following so far :

  1. use this url to get access token in the url parameter from redirect (after user login)
  "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?"
  +"client_id={CLIENT_ID_HERE}"
  +"&response_type=token"
  +"&redirect_uri=http%3A%2F%2Flocalhost%3A8100%2F"
  +"&scope=offline_access openid contacts.read contacts.read.shared user.read"
  +"&nonce=89289"//tried both with and without this
  +"&response_mode=fragment";

I get an access token in the redirect url, but its actually invalid, eg :

EwBoA8l6BAAUO9chh8cJscQLmU%2bLSWpbnr0vmwwAASwN7zn/GFDP4wdOkrbA8xsurg0RceNlSsJiBj8uqZkK2E%2bmWTXjrj89FuiSlBcKqAe6dyuEbTOn8YBu3xApWaBKZjuP5lJZnAnWZX80Il7VtWMh2UuK/s4qxOZRYcgJEhwe8iTrPOGofm5Z3oU2o1MzGpSa6qaR1AleeKF9q0hZoV99BKLfRUOueK7LRwpnF4mGjLjTevNCUDGIo1N38FPH5bFPhSfAOVDSV%2bw7ZZO6NAS5Vo6HdgbPWC3Eml9Ix4twyzpgf7e4Q0l3oi%2b23iPtTvyNV16cEtt9jehdZ1TjSLdMj92Yc7e18Y%2bwV1SGav1qZ2Lyd/e3xNDmZz1P%2bSkDZgAACIkGgjdNZrtHOALgj5s3vZkDiURxDQzucVxbzf/p1XCG9qfCStUazMWbp9KlGkpIgHyigTVJfUVjYwht8X77wC3Oa%2btShphq2myn4C7LZp7nfpwGz4bSW0lx42SG2ADn33qu2hh4Mc%2bdJskI4pxGOUnurKnxFH0sxKpCisIIiWylPOgiOqCzH9AGyEaat91glrwzaHfKXXgzMeO88PeEjZ5Rfj0q4dxd4OTv67E8cp%2bXeYhhHerElKMi2LJmt65heTfwLOd7ErVawl9dS77nyMNp1OCow%2bvSysLuvHNCzN9gsUtMgH7a0C78t6cm1NiNsa8Yzk2yZ%2bjPiiNGgilvyv1zSMvAwYrcGjSW/yHY%2bQfn0ijEeo3Qq2tczoq/8/mx3kV50qNla5BWHltaMvwqxxQqk/ZXIJrph9qQsnPcRJcjtvXaSatMPwFoiBYLqTyezcYq6rbvLxbsiEhtE9pQMvMpmu2lzbEdnGYKtMQVjIbBJB7brzFDJ%2bmG2YdLPA9vmsqrmOJM8ZiftWRrDW9alMrml%2bcscmO1vqJuftn3uylvhnAQZP3q40CicqyEcrwSBA29%2bFQGbG/BDIHH0rtUXPsMkwKneJYluVXfMbxUlUxUJhCS79Dd4Jjrk3RX7QWj1WwEz9WlYAwyP0s/PnqPQOVodnwMaHNo%2bV2Xk1/5xi5dcU/Tt2TPJvCvHfS7p4i3%2bKlwTgn2llRMFkVFbf32BM2oaQPlSL7CPDU27IPGoW1xYSYa7ZdNjqvBGak1UNNee%2bStggI%3d
  1. Similar to above, but I get id_token from that (so response_type=id_token instead). And then I silently request access token using GET request with this url :
      "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?";
      "client_id={CLIENT_ID_HERE}"
      +"&response_type=token"
      +"&redirect_uri=http%3A%2F%2Flocalhost%3A8100"
      +"&scope=offline_access openid contacts.read contacts.read.shared user.read"
      +"&response_mode=fragment"
      +"&prompt=none";

With that I get a CORB error (which i see in console) but in the network tab, it shows the status code was 200. Somehow, the request method is showing as OPTIONS (even though i made a GET request). I'm not sure why this is.

I'm not sure what I'm doing wrong, but does anyone know how I can obtain a valid access token?

Access to XMLHttpRequest at 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=XXXXX
&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%3A8100&scope=offline_access%20openid%20contacts.read
%20contacts.read.shared%20user.read&response_mode=fragment&prompt=none' from origin 'http://localhost:8100' has been 
blocked by CORS policy: Response to preflight request doesn't pass access control check: No 
'Access-Control-Allow-Origin' header is present on the requested resource.


Cross-Origin Read Blocking (CORB) blocked cross-origin response 
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=XXXX&response_type=token&redirect_uri=
http%3A%2F%2Flocalhost%3A8100&scope=offline_access%20openid%20contacts.read%20contacts.read.shared%20user.read
&response_mode=fragment&prompt=none with MIME type text/html. See
https://www.chromestatus.com/feature/5629709824032768 for more details.
  • Your code needs to cause users to be navigated/redirected to `https://login.microsoftonline.com/common/oauth2/v2.0/authorize` where they manually login and then after that will redirect back to your frontend, right? See the answer at https://stackoverflow.com/a/47821607/441757 etc. Typically that means you need to a button or link in your frontend UI that users follow/use. But whatever frontend code you have now, it’s not doing that; instead it’s causing a XHR request to be made to that URL. As far as I understand, that’s not gonna work and is intentionally not supported. – sideshowbarker Nov 29 '19 at 02:03
  • See also the answers at https://stackoverflow.com/a/41986679/441757 https://stackoverflow.com/a/38319300/441757, and the docs at https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow: *“ the Microsoft identity platform endpoint does not support CORS requests, so making AJAX calls to get and refresh tokens is out of the question. Instead, you can use the implicit flow in a hidden iframe to get new tokens for other web APIs”* – sideshowbarker Nov 29 '19 at 02:08
  • @sideshowbarker I am using the implicit flow (or at least, trying to). when I make the get request from my angular service, it gives me a CORB (error shown in question). Since the response to that request is the signin page, what I'm doing rn is when the user clicks on the button, it opens up the url in the same page. i.e. leaves my app and goes to microsoft sign in page. – user12247970 Nov 29 '19 at 02:48
  • @sideshowbarker As to what you said about my code causing a XHR request to be made : I tried both ways. The first was just clicking on button causes the app to open that url in the same tab (like you said it should). In that case, it does return an access token in the url. The problem is, its invalid (basically the first option i tried and I've shown the result for that in the question). Maybe the way I phrased the question was confusing. Basically, I want a valid access token. Method 1 returns a token, but thats invalid. Method 2 gives a CORB error. Not sure what to do next – user12247970 Nov 29 '19 at 02:50

1 Answers1

0

You didn't specify which API you are using to get Outlook contacts so I'm assuming that it's some Graph API like this:

https://learn.microsoft.com/en-us/graph/api/user-list-contacts?view=graph-rest-1.0&tabs=http

If so then to get a valid token you need to replace "common" with your tenantID

Here's a sample of what works for me:

  "https://login.microsoftonline.com/{TENANT_ID_HERE}/oauth2/v2.0/authorize?"
  +"client_id={CLIENT_ID_HERE}"
  +"&response_type=code"
  +"&redirect_uri=http%3A%2F%2Flocalhost%3A8100%2F"
  +"&scope=offline_access openid contacts.read contacts.read.shared user.read"
  +"&state={STATE_HERE}
  +"&response_mode=query";

https://learn.microsoft.com/en-us/graph/auth-v2-user?context=graph%2Fapi%2F1.0&view=graph-rest-1.0

Where did you get "response_mode=fragment" and "response_type=token" from? That doesn't even look to be valid?

Ryan
  • 313
  • 3
  • 12
  • I'm using the implicit flow. The second link you gave shows a 2 step process, but the /token endpoint actually gives a CORS error when I make the request so to avoid that, use this https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow also, the docs mention "The {tenant} value in the path of the request can be used to control who can sign into the application. " so if I put my tenant id, then other users cant login, which is not what i want. – user12247970 Nov 29 '19 at 01:47