【问题标题】:ADAL.JS with Mobile AppADAL.JS 与移动应用程序
【发布时间】:2017-08-05 09:24:54
【问题描述】:

我正在尝试将一些 Oracle 交付的移动应用程序框架应用程序 (MAF) 移动应用程序与 Azure AD 身份验证集成。我已经尝试过 Java 方法,显然是 doesn't work in my case

所以我决定尝试使用 ADAL.JS 的 Javascript 登录页面选项。由于 MAF 通过转译为 HTML 5/Javascript/Cordova 创建了跨平台兼容代码,我认为我可以使 JS 选项工作,而无需借助 ADAL-Android 或 ADAL-IOS 等多个 SDK 特定解决方案。因为我可以将它全部包装在 HTML 页面中,因为我可以使用 ADAL.JS 所需的 OAUTH 隐式流选项。我的 ADAL.JS 部分在我的 PC 上工作,使用 this example 和本地 Node/Webpack 开发服务器作为重定向 URI。 (注意,就像那个例子一样,我更喜欢使用严格的 adal.js 选项并避免使用任何 angular-js 的东西)。但是,我在 Android 移动设备上部署时遇到了问题。这似乎是由于回复 URI。在提示输入 Azure 凭据并提供这些凭据后,会产生以下错误。

AADSTS50011:回复地址“file:///data/user/0/com.company.app/storage/assets/FARs/ViewController/public_html/SignOn/login.html”的方案无效。

我发现在部署到移动设备时,Azure 注册的应用程序必须设置为键入“Native”而不是我所做的“Web/API”。并且根据一个 MSFT 示例(我不能包含该示例,因为我没有足够的代表来包含两个以上的链接)重定向 URI 必须设置为“https://login.microsoftonline.com/common/oauth2/nativeclient”。但我仍然得到同样的错误。

@FeiXue 回复后更新

我使用的是原始端点而不是 2.0。当我这样设置redirectURI时:

redirectURI=https://login.microsoftonline.com/common/oauth2/nativeclient

浏览器在地址栏中返回此信息,并保持在空白屏幕上,并且不发出令牌。它在 PC 浏览器和移动浏览器上都执行此操作。

http://login.microsoftonline.com/common/oauth2/nativeclient# id_token 强> = eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzUU4wQlpTN3M0bk4tQmRyamJGMFlfTGRNTSIsImtpZCI6ImEzUU4wQlpTN3M0bk4tQmRyamJGMFlfTGRNTSJ9。(缩短为了简洁)状态= e1ce94fb-6310-4dec-9e8b-053727ceb9b8&session_state = 1beafa4d-af55-415b-85d5-83e8b4035594 P>

但是,对于完全相同的代码,当我在 PC 上设置 redirectURI 时,它会返回一个访问令牌:

redirectURI=https://localhost:8443

我也尝试过使用 urn:ietf:wg:oauth:2.0:oob 的 redirectURI,但这也不起作用。

代码

<!DOCTYPE html>
<html>
<head>
    <title>Authenticate User with ADAL JS</title>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.0/js/adal.js"></script>
    <script type="text/javascript">
        $(document).ready(function() {
            "use strict";

            var variables = {
                azureAD: "mytenant.onmicrosoft.com",
                clientId: "cc8ed7e0-56e9-45c9-b01e-xxxxxxxxxx"
            }

            window.config = {
                tenant: variables.azureAD,
                clientId: variables.clientId,
                postLogoutRedirectUri: window.location.origin,
                redirectUri: "https://login.microsoftonline.com/common/oauth2/nativeclient",
                endpoints: {
                    aisApiUri: "cc8ed7e0-56e9-45c9-b01e-xxxxxxxxxx"
                }
                //cacheLocation: "localStorage"
            };

            var authContext = new AuthenticationContext(config);

            var isCallback = authContext.isCallback(window.location.hash);

            authContext.handleWindowCallback();

            if (isCallback && !authContext.getLoginError()) {
                window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
            }

            var user = authContext.getCachedUser();

            if (!user) {

                authContext.login();
            }

            authContext.acquireToken(config.endpoints.aisApiUri, function (error, token) {
                if (error || !token) {
                    console.log("ADAL error occurred in acquireToken: " + error);
                    return;
                }
                else {

                    var accessToken = "Authorization:" + " Bearer " + token;

                    console.log("SUCCESSFULLY FETCHED TOKEN: " + accessToken);

                }
            });

        });
    </script>
</head>
<body>
    <h1>Test Login</h1>
</body>
</html>

更新

@FeiXue 所以我猜你所说的 id_token 是访问令牌吗?我认为那么问题是这样的。

当 redirectURI="https://localhost:8443" 在 AAD 登录后重定向回我的 index.html 并且 authContext.acquireToken() 工作并返回有效令牌。

但是当 redirectURI="https://login.microsoftonline.com/common/oauth2/nativeclient" 它永远不会从http://login.microsoftonline.com/common/oauth2/nativeclient#重定向回来id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1Ni......

虽然它显示 id_token,但它永远不会重定向回我的 index.html 所以我无法调用 authContext.acquireToken() 将其传递到我的 Web API。

【问题讨论】:

    标签: azure-active-directory adal oracle-maf adal.js


    【解决方案1】:

    根据我对这个主题的研究,这里是 ADAL.JS 和本机(移动)设备支持的要点

    正如@fei-xue-msft 所述,ADAL.JS 不适用于本机/移动设备,也不适用于本机/移动设备。 ADAL.JS 在编写时考虑了“原始”Azure 端点,而不是为移动/本机设备提供更多功能的 v2.0 端点(有关两个不同端点选项的更多信息,请参见下文)。但是,您可以尝试experimental ADAL.JS branch(使用 v2.0 端点),但它不再被主动更新,因此您只能靠自己了。新的 MSFT 方法是使用针对 v2.0 端点编写的新 MSAL 库。然而,目前还没有 MSAL-for-JS 库,但有传言称在某个时候会有一个。有关两个不同 Azure 端点(“原始”与“v2.0”)的更多信息,请参阅下面的链接。对此的困惑是我在故障排除时感到沮丧的根源,因此我帮助这有助于其他一些人走上这条轨道。

    因此,如果您希望在移动设备上获得 Azure Oauth 身份验证,请首先确定您要使用的 Azure 端点(下面的支持链接作为 v2.0 确实有一些原始端点没有的限制)。您可以通过查看下面列出的元数据文档链接来确定您的租户的特定端点是什么,只需替换您的租户名称或 ID。你应该可以使用任何一个。

    要为特定类型的端点(原始与 v2.0)注册应用程序,请使用下面引用的相应应用程序注册门户链接。然后,要确定为本地/移动设备创建 Azure 身份验证解决方案的选项,请查看每个端点版本的代码示例,并确保该示例适用于“本地”,否则它可能无法在您的移动设备上运行.例如,您不会看到原始端点库选项的 ADAL.JS 示例,但您会看到 Cordova 的示例(这就是 @fei-xue-msft 建议采用这种方法的原因)。对于 v2.0 端点示例,您将看到 MSAL/Xamarin 选项,对于 Javascript 选项,您可以尝试类似 Hello.JS Sample 的方法。

    原始端点

    https://login.microsoft.com/{租户 id}/oauth2/authorize

    应用注册门户: https://portal.azure.com

    代码示例: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-code-samples#native-application-to-web-api

    原生身份验证场景: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-scenarios#native-application-to-web-api

    OpenID 元数据文档: https://login.microsoft.com/{tenant id}/.well-known/openid-configuration


    V2.0 端点

    https://login.microsoftonline.com/{租户ID}/oauth2/v2.0/authorize

    应用注册门户:https://apps.dev.microsoft.com

    V2.0 端点比较: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-compare

    代码示例: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-libraries

    OpenID 元数据文档: https://login.microsoft.com/{tenant id}/v2.0/.well-known/openid-configuration

    【讨论】:

      【解决方案2】:

      您是否使用 Azure AD V2.0 端点进行开发?

      如果没有,我们可以根据需要在 本机应用程序 的门户上配置 重定向 URI。但是,由于错误消息表明文件协议不是验证方案。

      在这种情况下,我们可以使用 http 或 https,因为您是使用 HTML 开发的。

      并且在 Azure AD V2.0 端点中,我们目前无法为本机应用设置 redirect_Uri。我们可以使用urn:ietf:wg:oauth:2.0:oobhttps://login.microsoftonline.com/common/oauth2/nativeclient 作为redirect_Uri。第一个用于设备的 native 应用,第二个用于在浏览器中托管的客户端(网络视图)。

      最后,请确保请求中的 redirect_uri 使用的是您为门户注册的正确的。您还可以在浏览器上测试请求,以缩小此问题是否导致请求中的 redirect_uri 不正确。对于授权请求,您可以参考以下链接:

      Authorize access to web applications using OAuth 2.0 and Azure Active Directory

      v2.0 Protocols - OAuth 2.0 Authorization Code Flow

      更新(如果从磁盘打开 HTML 导致弹出页面未关闭,则没有 href 属性)

      AuthenticationContext.prototype._loginPopup = function (urlNavigate) {
              var popupWindow = this._openPopup(urlNavigate, "login", this.CONSTANTS.POPUP_WIDTH, this.CONSTANTS.POPUP_HEIGHT);
              if (popupWindow == null) {
                  this.warn('Popup Window is null. This can happen if you are using IE');
                  this._saveItem(this.CONSTANTS.STORAGE.ERROR, 'Error opening popup');
                  this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, 'Popup Window is null. This can happen if you are using IE');
                  this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, 'Popup Window is null. This can happen if you are using IE');
                  if (this.callback)
                      this.callback(this._getItem(this.CONSTANTS.STORAGE.LOGIN_ERROR), null, this._getItem(this.CONSTANTS.STORAGE.ERROR));
                  return;
              }
              if (this.config.redirectUri.indexOf('#') != -1)
                  var registeredRedirectUri = this.config.redirectUri.split("#")[0];
              else
                  var registeredRedirectUri = this.config.redirectUri;
              var that = this;
              var pollTimer = window.setInterval(function () {
                  if (!popupWindow || popupWindow.closed || popupWindow.closed === undefined) {
                      that._loginInProgress = false;
                      window.clearInterval(pollTimer);
                  }
                  try {
                      //there is no href property if open the HTML from disk
                      if (popupWindow.location.href.indexOf(registeredRedirectUri) != -1) {
                          if (that.isAngular) {
                              that._onPopUpHashChanged(popupWindow.location.hash);
                          }
                          else {
                              that.handleWindowCallback(popupWindow.location.hash);
                          }
                          window.clearInterval(pollTimer);
                          that._loginInProgress = false;
                          that.info("Closing popup window");
                          popupWindow.close();
                      }
                  } catch (e) {
                  }
              }, 20);
          };
      

      这个问题是因为当我们从设备(磁盘)打开HTML页面时,父HTML页面(登录页面)无法获取弹出页面的位置。因此父页面无法根据弹出页面的位置关闭该页面。为了解决这个问题,我建议您使用azure-activedirectory-library-for-cordova 进行开发或将登录页面托管在 Web API 的后端。

      【讨论】:

      • 感谢您的回复。请在原帖中查看我的更新。发表评论太长了。
      • 无法准确理解问题?它在响应 htttp://login.microsoftonline.com/common/oauth2/nativeclient#id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzUU4wQlpTN3M0bk4tQmRyamJGMFlfTGRNTSIsImtpZCI6ImEzUU4wQlpTN3M0bk4tQmRyamJGMFlfTGRNTSJ9.(shortened for brevity)&amp;state=e1ce94fb-6310-4dec-9e8b-053727ceb9b8&amp;session_state=1beafa4d-af55-415b-85d5-83e8b4035594 中返回 id_token
      • id_token 不是 access_token。 Id_token 是您的应用在使用 OpenID Connect 执行身份验证时收到的一种登录安全令牌(请参阅与 here 的区别)。如果您希望重定向到htttps://localhost:8443,您应该注册并使用此重定向 URL,而不是 Azure 的内置 URL。 Azure AD 根据请求中的参数response_type 颁发令牌。
      • 例如,我们可以在隐式流中像response_type=token+id_token一样设置这个参数,以确保Azure AD在响应中同时返回access_token和id_token。您可以参考 Azure AD 的 metadata link 获取 Open Id 连接,了解它支持的所有 response_type。
      • 了解令牌,谢谢。但是对于没有监听 Web 服务器端口的移动设备,redirectURI 应该是什么? "redirectURI="htttps://login.microsoftonline.com/common/oauth2/nativeclient" 不起作用,因为它永远不会重定向回我在上面的更新中描述的发起登录请求的网页。
      猜你喜欢
      • 2016-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-15
      • 2012-02-03
      相关资源
      最近更新 更多