如何将azure广告整合到一个反应网络应用程序中,该应用程序也在使用天蓝色的REST API

Lui*_*cia 14 javascript reactjs azure-active-directory adal adal.js

我有一个Web应用程序是React,我已经为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);
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

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 };
Run Code Online (Sandbox Code Playgroud)

在此之前一切正常,当用户未经过身份验证时,会将其重定向到login.live.com进行身份验证,然后将其重定向回来.

但是,我还创建了另一个用于托管REST API的azure webapp,REST API已经在Azure AD中配置,因此尝试使用其余部分的用户需要进行身份验证.

现在的问题是:如何设置我的客户端APP以使用受Azure AD保护的REST API.

我找到了这个,看起来我正在寻找什么,但我不知道如何将它集成到我上面的现有代码中

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

更新:对于潜在的读者

这个答案加上这个网址上的说明配置应用程序注册帮助我解决了这个问题:https://blog.ithinksharepoint.com/2016/05/16/dev-diary-s01e06-azure-mvc-web-api-angular -and-阿达勒-JS-和-401S /

Phi*_*ret 10

这里的关键是adalApiFetch,定义于adalConfig.js.如您所见,它是一个简单的包装器adalFetch.此方法(在中定义react-adal)接收ADAL实例(authContext),资源标识符(resourceGuiId),方法(fetch),URL(url)和对象(options).该方法执行以下操作:

  1. 使用ADAL实例(authContext)获取标识的资源的访问令牌resourceGuiId.
  2. 将此访问令牌添加到对象的headers字段options(如果未提供,则创建一个).
  3. 调用传入的给定"fetch"方法urloptions作为参数的对象.

adalApiFetch方法(您在已定义adalConfig.js)简单的调用adalFetch与所标识的资源adalConfig.endpoints.api.

好的,那么如何使用所有这些来发出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);
Run Code Online (Sandbox Code Playgroud)

index.js包装indexApp.jsrunWithAdal从方法react-adal,这确保了用户在装载之前天青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);
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)