Office 365 График API от JavaScript: Как правильно аутентифицировать -- javascript поле с участием office365 пол Связанный проблема

office 365 graph api from javascript: how to properly authenticate


6
vote

проблема

русский

Я не ненавижу ОАУТ, но я ненавижу себя, потому что не смог обернуть голову вокруг концепции. Сказав это, вот мой вопрос: я пытаюсь позвонить в API Office Graph Rest из Vanilla JavaScript. Поэтому я делаю обычный XMLHTTPREQUEST TO GROST.MICROSOFT.com, с страницы, которая работает на моем онлайн-сайте SharePoint (поэтому код должен запускать из моего контекста безопасности, как я вошел в систему). Вызов возвращает необходимую аутентификацию 403. Я предполагаю, что я должен зарегистрировать приложение в Azure AD, и я сделал это, поэтому у меня есть идентификатор клиента и секрет. Тем не менее, я не могу найти, что делать дальше программно (I думаю, что я понимаю понятие, я должен получить токен, который я должен предоставить при вызове графа API). Кажется, есть тонны примерного кода для почти ничего, за исключением JavaScript. У кого-нибудь есть указатели?

Обновление: Я знаю вовлечение токена, и это часть, которую я не могу обернуть голову (см. Оригинальный вопрос / комментарий); У меня есть идентификатор клиента, у меня есть секрет, и у меня есть этот (очень распространенный) код:

 <код> function graphRead(whatToRead) {  switch(whatToRead) {     case "userinfo" :         officeUser = JSON.Parse(loadXMLDoc("GET","https://graph.microsoft.com/v1.0/me"));         break;     default:     }; };  function loadXMLDoc(mMethod,uURL) {     var xmlhttp;      if (window.XMLHttpRequest) {         // code for IE7+, Firefox, Chrome, Opera, Safari         xmlhttp = new XMLHttpRequest();     } else {         // code for IE6, IE5         xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");     }      xmlhttp.onreadystatechange = function() {         if (xmlhttp.readyState == XMLHttpRequest.DONE ) {            if(xmlhttp.status == 200){                return(xmlhttp.responseText);            }            else if(xmlhttp.status == 400) {               alert('There was an error 400')            }            else {                alert('something else other than 200 was returned')            }         }     };      xmlhttp.open(mMethod, uURL, true);     xmlhttp.send(); };   

Вопрос: Что мне нужно сделать, чтобы установить токен и отправить его на API?

Английский оригинал

I don't hate Oauth, but I hate myself for not being able to wrap my head around the concept. Having said that, here's my question: I'm trying to call the Office Graph REST api from vanilla javascript. So I'm doing a regular XMLHttpRequest to graph.microsoft.com, from a page which runs on my SharePoint Online site (therefore the code should run from my security context, as I am logged in). The call returns a 403 Authentication Required. I assume I have to register an app in Azure AD and I have done that, so I have a Client ID and a secret. However, I cannot find what to do next programmatically (I think I understand the concept, I have to get a token that I have to provide when calling the Graph api). It seems there's tons of sample code for just about anything, with the exception of javascript. Does anyone have pointers?

Update: I know the involvement of the token, and that's the part I can't wrap my head around (see original question/comment); I have a Client ID, I have a secret, and I have this (VERY common) code:

function graphRead(whatToRead) {  switch(whatToRead) {     case "userinfo" :         officeUser = JSON.Parse(loadXMLDoc("GET","https://graph.microsoft.com/v1.0/me"));         break;     default:     }; };  function loadXMLDoc(mMethod,uURL) {     var xmlhttp;      if (window.XMLHttpRequest) {         // code for IE7+, Firefox, Chrome, Opera, Safari         xmlhttp = new XMLHttpRequest();     } else {         // code for IE6, IE5         xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");     }      xmlhttp.onreadystatechange = function() {         if (xmlhttp.readyState == XMLHttpRequest.DONE ) {            if(xmlhttp.status == 200){                return(xmlhttp.responseText);            }            else if(xmlhttp.status == 400) {               alert('There was an error 400')            }            else {                alert('something else other than 200 was returned')            }         }     };      xmlhttp.open(mMethod, uURL, true);     xmlhttp.send(); }; 

Question is: what do I need to do to establish the token and send it to the API?

</div
     

Список ответов

3
 
vote

Если вы делаете эту все на стороне клиента в JavaScript, вы, вероятно, захотите реализовать то, что известен как «неявный тоск». Azure есть запись процесса здесь: https://azure.microsoft.com/en-us/documentation/articles/ Active-directory-v2-protocols-implicling/ .

В основном ваша страница будет иметь ссылку «Войти», либо автоматически пропустите страницу авторизации Azure со всеми параметрами, кодированными, закодированными в URL, как идентификатор вашего клиента, а также призёмы, которые вы запрашиваете график. При необходимости пользователю придется войти в систему, но в вашем случае они могут не придется. Как только пользователь входит в систему со своими учетными данными (опять же, если необходимо), их просят предоставить согласие, чтобы позволить вашему приложению получить доступ к своим данным. Предполагая, что они говорят, да, Azure будет перенаправляться обратно на вашу страницу с токеном доступа в запросе HASHH. Вам нужно будет иметь код JS там, чтобы извлечь токен доступа из хеша. Например, перенаправление будет выглядеть что-то вроде:

 <код> https://localhost/myapp/# access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q... &token_type=Bearer &expires_in=3599 &scope=https%3a%2f%2fgraph.microsoft.com%2fmail.read  &id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q... &state=12345   

<Сильные> псевдо-шаги

  1. на странице Загрузка, проверьте, есть ли уже токен доступа в фрагменте URL.
    1. , если это так, то указывает на вашу загрузку после перенаправления авторизации, и вы можете приступить к вызовам ваших графов.
    2. Если нет, то вам нужно подсказать пользователю или автоматически перенаправить на конечную точку авторизации.
  2. Вам нужно пройти токен в <код> Authorization HTTP-заголовок при вызове графа. Вы можете сделать это, добавив следующую строку в свой код (до <код> send ): <код> xmlhttp.setRequestHeader("Authorization", "Bearer " + token);

Но почему я должен сделать это?

Ответ заключается в том, что OAuth все о запуске как приложение, не работает как пользователь. Таким образом, старая модель приложения аутентично, как пользователь не применяется. Пользователь должен предоставить разрешения для приложения для доступа к своим данным.

Так что действительно, что здесь происходит, не так ли приложение для «Auth» снова как пользователь «, он должен автор, как себя! Это действительно то, что вы делаете (предоставляя свой идентификатор клиента). В рамках этого процесса пользователь может войти в систему, чтобы подтвердить их удостоверение личности, а затем предоставить согласие.

Ваш секрет клиента не будет использоваться вообще в неявный поток. По сути, ваше приложение «доказывает», это действительно сам по себе, используя идентификатор клиента и присутствую на URL-адресе, который вы регистрируете как часть вашего приложения.

 

If you're doing this all client-side in JavaScript, you likely want to implement what's known as the "implicit grant" flow. Azure has a write up of the process here: https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-protocols-implicit/.

Basically your page would either have a "sign in" link or would automatically browse to the Azure authorization page with all of the parameters encoded into the URL like your client ID and the scopes you are requesting to the Graph. If needed, the user will have to log in, but in your case they may not have to. Once the user logs in with their credentials (again, if needed), they would be asked to grant consent to allow your app to access their data. Assuming they say yes, Azure would redirect back to your page with the access token in a query hash. You'd need to have JS code there to extract the access token from the hash. For example, the redirect would look something like:

https://localhost/myapp/# access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q... &token_type=Bearer &expires_in=3599 &scope=https%3a%2f%2fgraph.microsoft.com%2fmail.read  &id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q... &state=12345 

Pseudo-steps

  1. On page load, check if there's already an access token in the URL fragment.
    1. If so, that indicates your loading after an authorization redirect, and you can proceed to make your Graph calls.
    2. If not, then you need to prompt the user or auto-redirect to the authorization endpoint.
  2. You need to pass the token in the Authorization http header when calling Graph. You can do this by adding the following line to your code (before the send): xmlhttp.setRequestHeader("Authorization", "Bearer " + token);

But why do I have to do this?

The answer is that OAuth is all about running as the app, not running as the user. So the old model of the app authenticating as the user doesn't apply. The user has to grant permissions to the app to access their data.

So really what's happening here isn't that the app is having to "auth again as the user", it has to auth as itself! That's really what your doing (by providing your client ID). As part of that process, the user may have to log in to confirm their identity, then provide consent.

Your client secret would not be used at all in the implicit flow. Essentially your app would "prove" it is really itself by using the client ID and being present at the URL you register as part of your app registration.

</div
 
 
       
       
2
 
vote

Библиотека ADAL.JS сделает жизнь намного проще для всех аутентификации ОАУТ против Adure AD, в том числе то, что вы пытаетесь сделать с использованием неявного согласия OAUTH из блока SharePoint JS.

  1. Зарегистрируйте приложение в разделе Azure AD приложения AD. Отредактируйте манифест и активируйте неявную ОАУТ. Добавить " https://mytenant.sharepoint.com " в списке URL-адреса ответа приложения.
  2. Вставьте этот код JS в редактор скрипта SharePoint, чтобы авторизовать пользователю, получить токен доступа и вызовите график API:

 <Код> <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.10/js/adal.min.js"></script>  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>    <body>    <div><a href="#" onclick="login();return false;">login</a>    </div>    <div><a href="#" onclick="getToken();return false;">get access token and user info</a>    </div>    </body>  <script type="text/javascript">    var configOptions = {      clientId: "insert Azure App ClientId here",      postLogoutRedirectUri: window.location.origin,    }      var accessToken = null;      window.authContext = new AuthenticationContext(configOptions);      var isCallback = authContext.isCallback(window.location.hash);    authContext.handleWindowCallback();      function getToken() {      authContext.acquireToken("https://graph.microsoft.com", function(error, token) {        console.log(error);        console.log(token);        accessToken = token;        getUsers();      })    }      function login() {      authContext.login();    }      function getUsers() {        $.ajax({        url: "https://graph.microsoft.com/v1.0/me",        type: 'GET',        headers: {          "Authorization": "Bearer " + accessToken        },        crossDomain: true,        success: function(response) {          console.log(response);          alert(response.userPrincipalName);        }      });      }  </script>  
 

The ADAL.js library will make life much easier for all OAuth authenticacion against Azure AD, including what you're trying to do using implicit OAuth consent from within a SharePoint js block.

  1. Register an app in your Azure AD applications section. Edit the manifest and activate implicit OAuth. Add "https://mytenant.sharepoint.com" to the app Reply Url list.
  2. Insert this JS code into a SharePoint Script Editor Webpart to authorize the user, get an access token and call the Graph API:

<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.10/js/adal.min.js"></script>  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>    <body>    <div><a href="#" onclick="login();return false;">login</a>    </div>    <div><a href="#" onclick="getToken();return false;">get access token and user info</a>    </div>    </body>  <script type="text/javascript">    var configOptions = {      clientId: "insert Azure App ClientId here",      postLogoutRedirectUri: window.location.origin,    }      var accessToken = null;      window.authContext = new AuthenticationContext(configOptions);      var isCallback = authContext.isCallback(window.location.hash);    authContext.handleWindowCallback();      function getToken() {      authContext.acquireToken("https://graph.microsoft.com", function(error, token) {        console.log(error);        console.log(token);        accessToken = token;        getUsers();      })    }      function login() {      authContext.login();    }      function getUsers() {        $.ajax({        url: "https://graph.microsoft.com/v1.0/me",        type: 'GET',        headers: {          "Authorization": "Bearer " + accessToken        },        crossDomain: true,        success: function(response) {          console.log(response);          alert(response.userPrincipalName);        }      });      }  </script>
</div
 
 
 
 

Связанный проблема

0  Функция обжига от Google Войти в кнопку, когда пользователь уже вписан в браузер  ( Firing function from google sign in button when user is already signed into brow ) 
Я пытаюсь иметь Google Войти на моем сайте. В настоящее время, если вы уже зарегистрированы в браузере, кнопка скажет «подписано» и <код> g_login() Функция...

6  Как обнаружить IE7 и ниже, используя jquery.support?  ( How to detect ie7 and lower using jquery support ) 
В настоящее время я использую jquery.browser для обнаружения IE7 и ниже <код> if ($.browser.msie && parseInt($.browser.version) <= 7) { //codes } Но...

30  Динамическое имя NG-контроллера  ( Dynamic ng controller name ) 
Я хочу динамически указать контроллер на основе конфигурации, которую мы загружаем. Что-то вроде этого: <код> <div ng-controller="{{config.controllerNameStr...

4  Создание нового пустого документа с JavaScript  ( Creating a new empty document with javascript ) 
Я работаю с некоторыми очень неразрушными XML (все теги - такие вещи, как «TX», «H», «VC»). Я хотел бы сделать копию этих данных, но со всеми тегами переиме...

0  Почему строковая переменная может использовать метод Foreach по вызову JS?  ( Why a string variable can use foreach method by call in js ) 
<Код> var rst = 0; var num = 0; Array.prototype.forEach.call(num + '', function(v){ rst += +v; }); Вы можете увидеть сверху. <Код> num - это ном...

0  транзакция внутри контура  ( Transaction inside a for loop ) 
Я хочу запустить транзакцию внутри контура. Мой код: - <код> n==00 Но проблема в том, что после оповещения (перед транзакцией) я напрямую получаю предупр...

-1  Откройте диалог поиска поля в CRM 2011 от JavaScript  ( Open the lookup dialog of a field in crm 2011 from javascript ) 
Как я могу запустить диалог поиска поля поиска, используя JavaScript? ...

1  Джейморфизм JavaScript: Как получить доступ к статическим атрибутам наследования класса в статическом методе («абстрактный») базовый класс?  ( Javascript polymorphism how to access static attributes of inheriting class in ) 
Я хотел бы иметь базовый класс и наследственный класс. Базовый класс должен обеспечить некоторую общую функциональность, которая зависит от свойств наследстве...

0  SVG D3 круговой контроль  ( Svg d3 circular control ) 
Я пытаюсь сделать контроль, в котором радиальные линии прилипают за пределами круга. Длина каждой линии, прилипающей зависит от значения данных. Короче говоря...

0  jQuery работает в Firefox, Safari, но не в Chrome  ( Jquery working in firefox safari but not in chrome ) 
Я написал какой-то код с JQuery Works в Firefox, Safari и IE9. Но Chrome это не нравится. Никаких очевидных MSG в Chrome Console не подходит. Я ударяю стену, ...

0  Регулировка часовой пояс в JavaScript на основе IP-адреса  ( Timezone adjustment in javascript based on ip location ) 
<Код> offset = new Date().getTimezoneOffset(); Это дает вам смещение временизона, основанное на компьютерных часах или часовой зоне браузера. Есть ли спосо...

0  jQuery: передача это к детской функции  ( Jquery passing this to child function ) 
У меня есть что-то подобное: <код> $('element.selector').live("click", function (){ run_some_func (); }); $('element.selector2').live("click", function...

0  Имея проблемы с использованием объема в jQuery  ( Having issues using a scope in jquery ) 
Так что я пытаюсь передать значение переменной FreeMarker ($ {item.uid}) на клик ссылки, чтобы запустить модаль с тем же уникальным значением идентификатора. ...

0  Как проверить функцию в жасмине  ( How to test a function in jasmine ) 
Может кто-нибудь помочь мне, пожалуйста? Я пытаюсь проверить функцию, которая вызывает функции FireBase, но когда я вызываю основную функцию и начните управля...

-3  Несоответствие массива JavaScript  ( Javascript array inconsistency ) 
У меня есть массив. Я бегу к проблемам, так что ... В моем коде я поместил следующий код отладки: <код> console.log(this.pages); console.log(this.pages.le...

Связанный проблема

0  Функция обжига от Google Войти в кнопку, когда пользователь уже вписан в браузер 
6  Как обнаружить IE7 и ниже, используя jquery.support? 
30  Динамическое имя NG-контроллера 
4  Создание нового пустого документа с JavaScript 
0  Почему строковая переменная может использовать метод Foreach по вызову JS? 
0  транзакция внутри контура 
-1  Откройте диалог поиска поля в CRM 2011 от JavaScript 
1  Джейморфизм JavaScript: Как получить доступ к статическим атрибутам наследования класса в статическом методе («абстрактный») базовый класс? 
0  SVG D3 круговой контроль 
0  jQuery работает в Firefox, Safari, но не в Chrome 
0  Регулировка часовой пояс в JavaScript на основе IP-адреса 
0  jQuery: передача это к детской функции 
0  Имея проблемы с использованием объема в jQuery 
0  Как проверить функцию в жасмине 
-3  Несоответствие массива JavaScript