web-dev-qa-db-ja.com

AzureのREST APIもAzureで使用する反応するWebアプリにAzure広告を統合する方法

ReactというWebアプリが1つあり、Webアプリ自体にAzure AD認証を既に構成しています。その100%クライアントサイトアプリ、サーバー側コンポーネントはありません。

このコンポーネントを使用しました: https://github.com/salvoravida/react-adal

私のコードは次のとおりです:adalconfig.js

import { AuthenticationContext, adalFetch, withAdalLogin } from 'react-adal';

export const adalConfig = {
  tenant: 'mytenantguid',
  clientId: 'myappguid',
  endpoints: {
    api: '14d71d65-f596-4eae-be30-27f079bf8d4b',
  },
  cacheLocation: 'localStorage',
};

export const authContext = new AuthenticationContext(adalConfig);

export const adalApiFetch = (fetch, url, options) =>
  adalFetch(authContext, adalConfig.endpoints.api, fetch, url, options);

export const withAdalLoginApi = withAdalLogin(authContext, adalConfig.endpoints.api);

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import DashApp from './dashApp';
import registerServiceWorker from './registerServiceWorker';
import 'antd/dist/antd.css';

import { runWithAdal } from 'react-adal';
import { authContext } from './adalConfig';

const DO_NOT_LOGIN = false;

runWithAdal(authContext, () => {

  ReactDOM.render(<DashApp />, document.getElementById('root'));

  // Hot Module Replacement API
  if (module.hot) {
    module.hot.accept('./dashApp.js', () => {
      const NextApp = require('./dashApp').default;
      ReactDOM.render(<NextApp />, document.getElementById('root'));
    });
  }

},DO_NOT_LOGIN);


registerServiceWorker();

dashapp.js

import React from "react";
import { Provider } from "react-redux";
import { store, history } from "./redux/store";
import PublicRoutes from "./router";
import { ThemeProvider } from "styled-components";
import { LocaleProvider } from "antd";
import { IntlProvider } from "react-intl";
import themes from "./settings/themes";
import AppLocale from "./languageProvider";
import config, {
  getCurrentLanguage
} from "./containers/LanguageSwitcher/config";
import { themeConfig } from "./settings";
import DashAppHolder from "./dashAppStyle";
import Boot from "./redux/boot";

const currentAppLocale =
  AppLocale[getCurrentLanguage(config.defaultLanguage || "english").locale];


const DashApp = () => (
  <LocaleProvider locale={currentAppLocale.antd}>
    <IntlProvider
      locale={currentAppLocale.locale}
      messages={currentAppLocale.messages}
    >
      <ThemeProvider theme={themes[themeConfig.theme]}>
        <DashAppHolder>
          <Provider store={store}>
            <PublicRoutes history={history} />
          </Provider>
        </DashAppHolder>
      </ThemeProvider>
    </IntlProvider>
  </LocaleProvider>
);
Boot()
  .then(() => DashApp())
  .catch(error => console.error(error));

export default DashApp;
export { AppLocale };

その時点まで、すべてが正常に機能します。ユーザーが認証されない場合、認証のためにlogin.live.comにリダイレクトされ、その後リダイレクトされます。

ただし、REST API、そのREST APIはAzure ADで既に構成されているため、残りを使用しようとするユーザー認証される必要があります。

ここでの質問は、Azure ADで保護されているAPI REST APIを消費するようにクライアント側のAPPを設定するにはどうすればよいですか?

私はこれを見つけて、探しているものを探しますが、これを上記の既存のコードに統合する方法がわかりません

https://github.com/AzureAD/Azure-activedirectory-library-for-js/issues/481

更新:潜在的な読者向け

この回答に加えて、アプリの登録を構成するためのこのURLの指示は、問題の解決に役立ちました: https://blog.ithinksharepoint.com/2016/05/16/dev-diary-s01e06-Azure-mvc-web -api-angular-and-adal-js-and-401s /

13
Luis Valencia

ここでのキーはadalApiFetchで、adalConfig.jsで定義されています。ご覧のとおり、これはadalFetchの単純なラッパーです。このメソッド( react-adal で定義)は、ADALインスタンス(authContext)、リソース識別子(resourceGuiId)、メソッド(fetch)を受け取ります、URL(url)およびオブジェクト(options)。このメソッドは次のことを行います。

  1. ADALインスタンス(authContext)を使用して、resourceGuiIdで識別されるリソースのアクセストークンを取得します。
  2. このアクセストークンをheadersオブジェクトのoptionsフィールドに追加します(または、提供されなかった場合は作成します)。
  3. urlおよびoptionsオブジェクトをパラメーターとして渡して、指定された「フェッチ」メソッドを呼び出します。

adalApiFetchメソッド(adalConfig.jsで定義した)は、adalConfig.endpoints.apiで識別されるリソースを使用してadalFetchを呼び出すだけです。

では、これらすべてを使用して、RESTリクエストを作成し、Reactアプリで応答を消費しますか?例を使用してみましょう。次の例では、Microsoft Graph APIをAzure AD保護されたREST APIとして使用します。わかりやすい識別子URI( " https:// graph .Microsoft.com ")、ただし、これはGuidアプリIDでもあり得ることに留意してください。

adalConfig.jsはADAL構成を定義し、いくつかのヘルパーメソッドをエクスポートします。

import { AuthenticationContext, adalFetch, withAdalLogin } from 'react-adal';

export const adalConfig = {
tenant: '{tenant-id-or-domain-name}',
clientId: '{app-id-of-native-client-app}',
endpoints: {
    api: 'https://graph.Microsoft.com' // <-- The Azure AD-protected API
},
cacheLocation: 'localStorage',
};

export const authContext = new AuthenticationContext(adalConfig);

export const adalApiFetch = (fetch, url, options) =>
adalFetch(authContext, adalConfig.endpoints.api, fetch, url, options);

export const withAdalLoginApi = withAdalLogin(authContext, adalConfig.endpoints.api);

index.jsindexApp.jsreact-adalrunWithAdalメソッドでラップします。これにより、ユーザーはAzureで署名されます。 indexApp.jsを読み込む前のAD:

import { runWithAdal } from 'react-adal';
import { authContext } from './adalConfig';

const DO_NOT_LOGIN = false;

runWithAdal(authContext, () => {

// eslint-disable-next-line
require('./indexApp.js');

},DO_NOT_LOGIN);

indexApp.jsは、単にAppのインスタンスをロードしてレンダリングします。

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

App.jsは魔法が発生するシンプルなコンポーネントです:

  • state値を定義します。この場合、生のAPIレスポンスを表示しているだけなのでapiResponseと呼ばれますが、もちろんこの状態に好きな名前を付けることができます(または複数の状態値を持つことができます)。
  • componentDidMount(要素がDOMで利用可能になった後に実行されます)の間に、adalApiFetchを呼び出します。 fetchフェッチAPI からfetchパラメーターとして渡し、REST要求を作成するためのエンドポイントMicrosoft Graphの/meエンドポイント(この場合):
  • renderメソッドでは、この状態値を<pre>要素に単純に表示します。
import React, { Component } from 'react';
import { adalApiFetch } from './adalConfig';

class App extends Component {

  state = {
    apiResponse: ''
  };

  componentDidMount() {

    // We're using Fetch as the method to be called, and the /me endpoint 
    // from Microsoft Graph as the REST API request to make.
    adalApiFetch(fetch, 'https://graph.Microsoft.com/v1.0/me', {})
      .then((response) => {

        // This is where you deal with your API response. In this case, we            
        // interpret the response as JSON, and then call `setState` with the
        // pretty-printed JSON-stringified object.
        response.json()
          .then((responseJson) => {
            this.setState({ apiResponse: JSON.stringify(responseJson, null, 2) })
          });
      })
      .catch((error) => {

        // Don't forget to handle errors!
        console.error(error);
      })
  }

  render() {
    return (
      <div>
        <p>API response:</p>
        <pre>{ this.state.apiResponse }</pre>
      </div>
    );
  }
}

export default App;
9