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 /
ここでのキーはadalApiFetch
で、adalConfig.js
で定義されています。ご覧のとおり、これはadalFetch
の単純なラッパーです。このメソッド( react-adal
で定義)は、ADALインスタンス(authContext
)、リソース識別子(resourceGuiId
)、メソッド(fetch
)を受け取ります、URL(url
)およびオブジェクト(options
)。このメソッドは次のことを行います。
authContext
)を使用して、resourceGuiId
で識別されるリソースのアクセストークンを取得します。headers
オブジェクトのoptions
フィールドに追加します(または、提供されなかった場合は作成します)。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.js
をreact-adal
のrunWithAdal
メソッドでラップします。これにより、ユーザーは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;