我有一个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);
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的Azure Web应用程序,该REST API已在Azure AD中进行配置,因此尝试使用其余API的用户将需要进行身份验证。
现在的问题是:如何设置客户端APP来使用受Azure AD保护的REST API?
我找到了它,并找到了我想要的东西,但是我不确定如何将其集成到上面的现有代码中
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)。该方法执行以下操作:
adalApiFetch
adalConfig.js
adalFetch
react- adal
authContext
resourceGuiId
fetch
url
options
headers
该adalApiFetch方法(您已在中定义adalConfig.js)仅adalFetch使用中标识的资源进行调用adalConfig.endpoints.api。
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);
index.jsindexApp.js使用runWithAdalfrom中的方法进行包装react- adal,以确保在加载之前使用Azure AD对用户进行签名indexApp.js:
indexApp.js
runWithAdal
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,在这里没什么花哨的:
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
componentDidMount
/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;