Как интегрировать azure ad в веб-приложение react, которое также использует REST API в azure
у меня есть одно веб-приложение React, и я уже настроил проверку подлинности 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);
.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 для аутентификации, а затем перенаправляется обратно.
однако я также создал еще один azure webapp для размещения REST API, который REST API уже настроен в Azure AD, так что пользователи, которые пытаются использовать rest, должны будут пройти проверку подлинности.
Теперь возникает вопрос: Как настроить приложение на стороне клиента для использования REST API, защищенного Azure AD.?
Я нашел это и выглядит то, что я ищу, но я не уверен, как интегрировать это в мой существующий код выше
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/
1 ответов
ключ здесь adalApiFetch
, определена в adalConfig.js
. Как вы можете видеть, это простая обертка вокруг adalFetch
. Этот метод (определяется в react-adal
) получает экземпляр ADAL (authContext
), идентификатор ресурса (resourceGuiId
), метод (fetch
), URL (url
) и объекта (options
). Метод делает следующее:
- используйте экземпляр ADAL (
authContext
) для получения маркера доступа к ресурсу, определенномуresourceGuiId
. - добавить этот доступ маркер .js обертывания
indexApp.js
СrunWithAdal
способ отreact-adal
, который гарантирует, что пользователь подписан с Azure AD перед загрузкойindexApp.js
: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
значение. В этом случае он называетсяapiResponse
поскольку мы просто показываем необработанный ответ API, но, конечно, вы можете назвать это государство, что вы хотели (или несколько значений). - во время
componentDidMount
(который запускается после того, как элемент доступен в DOM), мы делаем вызовadalApiFetch
. Проходим вfetch
(от Fetch API какfetch
параметр и конечная точка для запроса REST, который мы хотим сделать (/me
конечная точка в Microsoft Graph, в этом случае): - на
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;
- мы определяем