Reactjs Azure AD B2C未获取访问令牌

Reactjs Azure AD B2C未获取访问令牌,reactjs,azure,azure-active-directory,azure-ad-b2c,msal,Reactjs,Azure,Azure Active Directory,Azure Ad B2c,Msal,我有一个用JS编写的单页应用程序(SPA)。我正在尝试查询Graph API。我正在使用msal.js库来处理身份验证。我正在使用Azure AD B2C管理我的帐户。到目前为止,我所拥有的: 我可以登录谷歌并将我的个人资料信息返回我的SPA。但是,当请求accessToken时,结果为空。我肯定我做错了什么,我猜这是因为我的应用注册和范围。当我注册我的应用程序时,它有一个名为“user\u impersonation”的默认作用域。当我输入这个时,我意识到我注册了我的客户机(SPA),而不是A

我有一个用JS编写的单页应用程序(SPA)。我正在尝试查询Graph API。我正在使用msal.js库来处理身份验证。我正在使用Azure AD B2C管理我的帐户。到目前为止,我所拥有的:

我可以登录谷歌并将我的个人资料信息返回我的SPA。但是,当请求accessToken时,结果为空。我肯定我做错了什么,我猜这是因为我的应用注册和范围。当我注册我的应用程序时,它有一个名为“user\u impersonation”的默认作用域。当我输入这个时,我意识到我注册了我的客户机(SPA),而不是API。我需要两个都注册吗?我不知道该如何注册图形

我的代码:

App.js

import AuthService from '../services/auth.service';
import GraphService from '../services/graph.service';

class App extends Component {
  constructor() {
  super();
  this.authService = new AuthService();
  this.graphService = new GraphService();
  this.state = {
    user: null,
    userInfo: null,
    apiCallFailed: false,
    loginFailed: false
  };
}
  componentWillMount() {}

  callAPI = () => {
    this.setState({
    apiCallFailed: false
  });
  this.authService.getToken().then(
    token => {
      this.graphService.getUserInfo(token).then(
        data => {
          this.setState({
            userInfo: data
          });
        },
        error => {
          console.error(error);
          this.setState({
            apiCallFailed: true
          });
        }
      );
    },
    error => {
      console.error(error);
      this.setState({
        apiCallFailed: true
      });
    }
  );
};

logout = () => {
  this.authService.logout();
};

login = () => {
  this.setState({
    loginFailed: false
  });
  this.authService.login().then(
    user => {
      if (user) {
        this.setState({
          user: user
        });
      } else {
        this.setState({
          loginFailed: true
        });
      }
    },
    () => {
      this.setState({
       loginFailed: true
      });
    }
  );
};

render() {
  let templates = [];
  if (this.state.user) {
    templates.push(
      <div key="loggedIn">
        <button onClick={this.callAPI} type="button">
          Call Graph's /me API
        </button>
        <button onClick={this.logout} type="button">
          Logout
        </button>
        <h3>Hello {this.state.user.name}</h3>
      </div>
    );
  } else {
    templates.push(
      <div key="loggedIn">
        <button onClick={this.login} type="button">
          Login with Google
        </button>
      </div>
    );
  }
  if (this.state.userInfo) {
    templates.push(
      <pre key="userInfo">{JSON.stringify(this.state.userInfo, null, 4)}</pre>
    );
  }
  if (this.state.loginFailed) {
    templates.push(<strong key="loginFailed">Login unsuccessful</strong>);
  }
  if (this.state.apiCallFailed) {
    templates.push(
      <strong key="apiCallFailed">Graph API call unsuccessful</strong>
    );
  }
  return (
    <div className="App">
      <Header />
      <Main />
        {templates}
    </div>
  );
 }
}

export default App

graph.service.js
我在尝试查询Graph API时遇到访问被拒绝的错误,因此我将Graph.microsoft.com/1.0替换为httpbin,以便能够实际查看传入的内容。这就是我看到令牌为空的地方。这与我从微软的示例项目中提取的代码完全相同,当我使用他们的代码时,它就可以工作。他们没有展示的是AAD B2C和应用程序注册是如何配置的,我认为这就是我的问题所在

抱歉,这可能会让用户有点困惑,但这里有几种不同的服务

然后,在Azure AD B2C本身中,您可以为B2C部分提供支持。使用此应用程序注册,您无法使用任何图形

还有一个对图有效的法线。但是,这种类型的应用程序集成(也如所述)不能用于B2C

因此,再次明确指出:

您不能使用任何图形API(Azure AD图形API和 Microsoft Graph)从B2C应用程序的上下文中

您不能使用任何B2C功能(如使用谷歌登录、, 等)从“正常”应用程序的上下文中注册,以便与Graph一起使用


因此,在的上下文中,您只能请求和。

对不起,这可能会让用户感到有点困惑,但这里有几种不同的服务

然后,在Azure AD B2C本身中,您可以为B2C部分提供支持。使用此应用程序注册,您无法使用任何图形

还有一个对图有效的法线。但是,这种类型的应用程序集成(也如所述)不能用于B2C

因此,再次明确指出:

您不能使用任何图形API(Azure AD图形API和 Microsoft Graph)从B2C应用程序的上下文中

您不能使用任何B2C功能(如使用谷歌登录、, 等)从“正常”应用程序的上下文中注册,以便与Graph一起使用


因此,在的上下文中,您只能请求和。

我的问题是我需要注册2个应用程序:1个用于我的客户端,1个用于API。然后,在Azure AD B2C门户中,我必须授予客户端访问API的权限。一旦我这么做了,就会给我一个访问令牌

我的问题是我需要注册两个应用程序:一个用于客户端,一个用于API。然后,在Azure AD B2C门户中,我必须授予客户端访问API的权限。一旦我这么做了,就会给我一个访问令牌

发布你的代码!特别是你如何尝试获得访问令牌。你能组织你的一个具体问题吗。开始时,您讨论Azure功能,最后尝试调用Microsoft Graph。有两件事-首先,使用Azure AD B2C您不能使用MS Graph。第二步,阅读下面的文章:这似乎表明您可以(也应该)使用Graph API:发布您的代码!特别是你如何尝试获得访问令牌。你能组织你的一个具体问题吗。开始时,您讨论Azure功能,最后尝试调用Microsoft Graph。有两件事-首先,使用Azure AD B2C您不能使用MS Graph。第二步,阅读这篇文章,它似乎表明您可以(也应该)使用Graph API:我有同样的问题,这可以解决我的问题。要逐步做到这一点,请参阅官方Microsoft文档:我有相同的问题,这将解决我的问题。要逐步执行此操作,请参阅官方Microsoft文档:
import * as Msal from 'msal';

export default class AuthService {
constructor() {
// let PROD_REDIRECT_URI = 'https://sunilbandla.github.io/react-msal-sample/';
// let redirectUri = window.location.origin;
// let redirectUri = 'http://localhost:3000/auth/openid/return'
// if (window.location.hostname !== '127.0.0.1') {
//   redirectUri = PROD_REDIRECT_URI;
// }
this.applicationConfig = {
  clientID: 'my_client_id',
  authority: "https://login.microsoftonline.com/tfp/my_app_name.onmicrosoft.com/b2c_1_google-sisu",
  b2cScopes: ['https://my_app_name.onmicrosoft.com/my_api_name/user_impersonation email openid profile']
  // b2cScopes: ['graph.microsoft.com user.read']
};
this.app = new Msal.UserAgentApplication(this.applicationConfig.clientID, this.applicationConfig.authority, function (errorDesc, token, error, tokenType) {});
// this.logger = new Msal.logger(loggerCallback, { level: Msal.LogLevel.Verbose, correlationId:'12345' });
}


login = () => {
    return this.app.loginPopup(this.applicationConfig.b2cScopes).then(
    idToken => {
    const user = this.app.getUser();
    if (user) {
      return user;
    } else {
      return null;
    }
  },
   () => {
      return null;
    }
  );
};


logout = () => {
  this.app.logout();
};


getToken = () => {
  return this.app.acquireTokenSilent(this.applicationConfig.b2cScopes).then(
    accessToken => {
      return accessToken;
    },
    error => {
      return this.app
        .acquireTokenPopup(this.applicationConfig.b2cScopes)
        .then(
          accessToken => {
            return accessToken;
          },
          err => {
            console.error(err);
          }
        );
      }
    );
  };
}
export default class GraphService {
constructor() {
  // this.graphUrl = 'https://graph.microsoft.com/v1.0';
  this.graphUrl = 'http://httpbin.org/headers';
}

getUserInfo = token => {
  const headers = new Headers({ Authorization: `Bearer ${token}` });
  const options = {
    headers
  };
  return fetch(`${this.graphUrl}`, options)
    .then(response => response.json())
    .catch(response => {
      throw new Error(response.text());
    });
  };
}