【问题标题】:ADAL JS not attaching user token while invoking WebApiADAL JS 在调用 WebApi 时未附加用户令牌
【发布时间】:2017-05-28 21:26:42
【问题描述】:

我正在使用 ADAL JS 针对 Azure AD 对用户进行身份验证。由于我是 ADAL JS 的新手,我开始阅读以下文章,我觉得这些文章非常有用:

阅读文章后,我的印象是ADAL JS 拦截了服务调用,如果服务 url 在AuthenticationContext 配置中注册为端点之一,它会附加 JWT 令牌作为身份验证承载信息。

但是,我发现我的情况并没有发生同样的情况。经过一番挖掘,在我看来,只有在使用 adal-angular 计数器部件时才有可能,我目前没有使用它,仅仅是因为我的 Web 应用程序不是基于 Angular。

请让我知道我的理解是否正确。如果我需要显式添加承载信息,也可以这样做,但我更担心我是否缺少一些开箱即用的工具。

其他详细信息:我目前的配置如下所示:

private endpoints: any = {
    "https://myhost/api": "here_goes_client_id"
}
...
private config: any;
private authContext: any = undefined;
....
this.config = {
    tenant: "my_tenant.onmicrosoft.com",
    clientId: "client_id_of_app_in_tenant_ad",
    postLogoutRedirectUri: window.location.origin,
    cacheLocation: "sessionStorage",
    endpoints: this.endpoints
};
this.authContext = new (window["AuthenticationContext"])(this.config);

同样在服务器端(WebApi),认证配置(Startup.Auth)如下:

public void ConfigureOAuth(IAppBuilder app, HttpConfiguration httpConfig)
{
    app.UseWindowsAzureActiveDirectoryBearerAuthentication(
        new WindowsAzureActiveDirectoryBearerAuthenticationOptions
        {
            Tenant = "my_tenant.onmicrosoft.com",
            TokenValidationParameters = new TokenValidationParameters
            {
                ValidAudience = "client_id_of_app_in_tenant_ad"
            }
         });
}

但是,Authorizationrequest.Headers 中始终为空。

更新:似乎这同样适用于令牌的自动更新;当与adal-angular 一起使用时,令牌的更新可以通过在后台调用AuthenticationContext.acquireToken(resource, callback) 无缝进行。如果我错了,请纠正我。

【问题讨论】:

    标签: javascript azure asp.net-web-api adal.js


    【解决方案1】:

    阅读文章后,我的印象是 ADAL JS 拦截服务调用,如果服务 url 在 AuthenticationContext 配置中注册为端点之一,它会将 JWT 令牌作为身份验证承载信息附加。

    这仅在您的应用程序是基于角度的时才有效。正如你所提到的,这个逻辑存在于 adal-angular 中。

    但是,如果您想坚持使用纯 JS,您将无法获得自动“get-access-token-and-attach-it-to-header”支持。您可以使用acquireToken(resource, callback api 来获取端点的令牌。但是您必须在向 api 发送请求的控制器中做一些工作。

    这可能会给你一些想法:https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-dotnet-webapi/blob/master/TodoSPA/App/Scripts/Ctrls/todoListCtrl.js。此示例不使用角度。

    【讨论】:

      【解决方案2】:

      ADAL.JS 与 v2.0 隐式流不兼容。因为我最近设置了我的项目并且不认为项目向后兼容,所以我无法让它工作。

      这非常令人困惑,我花了很长时间才弄清楚我混淆了版本,并且不能将 ADAL.JS 与 v2.0 一起使用。一旦我删除它,事情就变得顺利多了,只是做了几个 XHR 请求和一个弹出窗口,实际上不需要任何魔法!

      这是 v2 的代码:

      function testNoADAL() {
          var clientId = "..guid..";
          var redirectUrl = "..your one.."
          var authServer = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?";
          var responseType = "token";
          var stateParam = Math.random() * new Date().getTime();
      
          var authUrl = authServer +
                                      "response_type=" + encodeURI(responseType) +
                                      "&client_id=" + encodeURI(clientId) +
                                      "&scope=" + encodeURI("https://outlook.office.com/Mail.ReadWrite") +
                                      "&redirect_uri=" + encodeURI(redirectUrl) +
                                      "&state=" + stateParam;
      
          var popupWindow = window.open(authUrl, "Login", 'width=' + 300 + ', height=' + 600 + ', top=' + 10 + ', left=' + 10 + ',location=no,toolbar=yes');
          if (popupWindow.focus) {
              popupWindow.focus();
          }
      }
      

      注意:redirectUrl 会出现在弹窗中,需要有代码来传递位置哈希,例如:

      <script>window.opener.processMicrosoftAuthResultUrl(location.hash);window.close();</script>

      function processMicrosoftAuthResultUrl(hash) {
          if (hash.indexOf("#") == 0) {
              hash = hash.substr(1);
          }
          var obj = getUrlParameters(hash);
          if (obj.error) {
              if (obj.error == "invalid_resource") {
                  errorDialog("Your Office 365 needs to be configured to enable access to Outlook Mail.");
              } else {
                  errorDialog("ADAL: " + obj.error_description);
              }
          } else {
              if (obj.access_token) {
                  console.log("ADAL got access token!");
                  var token = obj.access_token;
                  var url = "https://outlook.office.com/api/v2.0/me/MailFolders/Inbox/messages";
                  $.ajax({
                      type: "GET",
                      url: url,
                      headers: {
                          'Authorization': 'Bearer ' + token,
                      },
                  }).done(function (data) {
                      console.log("got data!", data);
                      var message = "Your latest email is: " + data.value[0].Subject + " from " + data.value[0].From.EmailAddress.Name+ " on " + df_FmtDateTime(new Date(data.value[0].ReceivedDateTime));
                      alertDialog(message);
      
                  }).fail(function () {
                      console.error('Error getting todo list data')
                  });
              }
          }
      }
      
      function getUrlParameters(url) {
          // get querystring and turn it into an object
          if (!url) return {};
          if (url.indexOf("?") > -1) {
              url = url.split("?")[1];
          }
          if (url.indexOf("#") > -1) {
              url = url.split("#")[0];
          }
          if (!url) return {};
          url = url.split('&')
          var b = {};
          for (var i = 0; i < url.length; ++i) {
              var p = url[i].split('=', 2);
              if (p.length == 1) {
                  b[p[0]] = "";
              } else {
                  b[decodeURIComponent(p[0])] = decodeURIComponent(p[1].replace(/\+/g, " "));
              }
          }
          return b;
      }
      

      【讨论】:

      • 这对我来说非常有趣。我也没有使用 angular,但能够部署和使用前面提到的sample ADAL.js non-angular app - 但是,唯一的缺点是 SPA 和 WebAPI 在同一个应用程序注册上。当我的 ADAL.js 位于不同的域和不同的应用注册时,我无法让启用 CORS 的 Web API 工作。
      • 摆脱 ADAL.js,它是遗留代码,不再受支持且不需要
      猜你喜欢
      • 2015-08-14
      • 2018-04-07
      • 1970-01-01
      • 1970-01-01
      • 2015-12-18
      • 2016-09-28
      • 2016-05-23
      • 1970-01-01
      • 2023-04-02
      相关资源
      最近更新 更多