首页 文章

使用ADAL.js获取令牌对Azure移动服务应用进行身份验证

提问于
浏览
6

我正在尝试针对Azure移动服务应用验证HTML应用 .

设置

两个应用程序都使用AAD作为身份验证后端,因此两个应用程序都在Active Directory中注册了一个应用程序:

Azure移动服务应用:

https://azure.microsoft.com/en-gb/documentation/articles/mobile-services-how-to-register-active-directory-authentication/中的描述配置

  • 我编辑了清单以启用客户端流程

  • 在"permissions to other applications"下为"Windows Azure Active Directory"启用"single sign-on and read users profiles"

HTML应用:

  • in "permissions to other applications"我添加了具有委派权限的Azure移动服务应用"access"

Azure移动服务使用.NET后端,其中包含并配置了NuGet包"Microsoft Azure Mobile Services .NET Backend Security Extension",如https://azure.microsoft.com/en-gb/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users/中所述

HTML应用程序使用ADAL.JS和Angular:

adalAuthenticationServiceProvider.init(
{
    // Config to specify endpoints and similar for your app
    clientId: "<html app aad client id>",
    redirectUri: "<html app redirect uri>",
    endpoints: {
        '<AMS app client id>': 'https://ampapp.azure-mobile.net/'
    }
},
$httpProvider
);

此设置按预期工作,我打开我的HTML应用程序,对Azure AD进行身份验证,重定向到我的应用程序并且我已登录 . 此外,当我尝试访问我的Azure移动服务时,我看到Adal.js注入持有者令牌 .

问题

Azure移动服务不接受承载令牌 - 我获得401未经授权 . 我不知道为什么,但Azure移动服务使用它自己的身份验证标头 - 但没关系 .

MSDN为Azure移动服务定义了一个所谓的“客户端定向登录操作”:

"Requests an authentication token from Microsoft Azure Mobile Services by using an identity token already obtained from an identity provider."(https://msdn.microsoft.com/en-us/library/azure/jj710106.aspx

好的,所以我们这样做:

// obtain token for Azure Mobile Service from Adal.js
 var token = this.getAADToken(ZUMOAuthenticationProvider.Config().url);

 $http({
        method: 'POST',
        url: ZUMOAuthenticationProvider.Config().url + 'login/aad', 
        data: JSON.stringify({
                  "access_token" : token 
              }),
        headers: {
                 'X-ZUMO-APPLICATION': '<application key>'
       }).
       success(function (data, status, headers, config) {
            alert(data);
       }).
       error(function (data, status, headers, config) {
            alert(data);
       });

注意:第一行获取的令牌实际上是azure移动服务和应用程序的访问令牌,而不是HTML应用程序的访问令牌 .

此POST请求也会收到401响应 . 所以我不知道如何验证我的应用程序 . 我也尝试了天蓝色的移动服务js lib . 这个lib工作正常,但它使用弹出窗口进行身份验证,但我不想在我的项目中添加另一个库来进行一些REST调用 .

类似的问题

在尝试解决我的问题时,我发现了其他Stackoverflow帖子:

Why isn't my Azure Mobile Service accepting the bearer token ADAL.js is sending it?

  • 同样的问题,没有解决方案(甚至在上次评论中链接的聊天记录中)

How do I secure an Azure Mobile Service with Azure AD? ADAL.JS

  • 与上面的作者相同,我检查了接受的答案中提到的所有内容,但它不起作用

我还看了一下来自新Azure管理门户的新Azure Mobile应用程序,但似乎他们使用相同的身份验证机制 .

那么,我怎样才能使这个工作?

3 回答

  • 0

    好的,我发现了我的错误:

    endpoints: {
        '<AMS app client id>': 'https://ampapp.azure-mobile.net/'
    }
    

    这应该是

    endpoints: {
        'https://ampapp.azure-mobile.net/': '<AMS app id uri>': 
    }
    

    在此之后它有效!我正在向github发布一个Angular模块,它将X-Auth-User标头中的标记注入到adal.js这样的每个请求中 .

    编辑:

    正如这里所承诺的更详细的答案:

    如我的问题中所述,您必须在Azure Active Directory中设置2个应用程序:

    • Azure移动服务的AAD应用程序

    • 只需按照article的说明操作

    • HTML应用的AAD应用

    • 将"oauth2AllowImplicitFlow"设为"true"

    • "permissions to other applications"下添加Azure移动服务AAD应用
      enter image description here

    配置Angular应用程序以将Azure Mobile服务用作 endpoints

    adalAuthenticationServiceProvider.init(
    {
        clientId:"54110492-4ae3-4c9f-9530-3101458d43fb",
        redirectUri: "https://localhost:44304/",
        endpoints: {
            'https://zumodemoapp.azure-mobile.net/': 'https://zumodemoapp.azure-mobile.net/login/aad'
        }
    },
    $httpProvider
    );
    

    现在,您可以使用Client-directed login operation获取Azure移动服务身份验证令牌 .

    var zumoAppID = 'https://zumodemoapp.azure-mobile.net/login/aad';
    var zumoLoginUri = 'https://zumodemoapp.azure-mobile.net/login/aad';
    var zumoTodoController = 'https://zumodemoapp.azure-mobile.net/tables/TodoItem';
    
    // 1. acquire a oath token for our zumo app from azure ad via adal.js
    adalAuthenticationService.acquireToken(zumoAppID).then(function (data) {
         //2. we have the azure ad token, lets get a azure mobile service token
         $http.post(zumoLoginUri,
                    JSON.stringify({
                        "access_token": data
                    })).
                    success(function (data, status, headers, config) {
                        //3. with the azure mobile service token we can authenticate our request
                        $http.get(zumoTodoController,
                                              {
                                                  headers:  {
                                                          'X-ZUMO-AUTH': data.authenticationToken
                                                  }
                                              }).
                                              success(function (data, status, headers, config) {
                                                  alert(data); //yay!
                                              });
                    }).
                    error(function (data, status, headers, config) {
                        alert(data);
                    });
    });
    

    正如评论中提到的,我创建了一个更详细的博客文章here . 如果您需要更多信息,请发表评论:) .

  • 0

    您可以使用AzureMobileServices客户端脚本使用已获取的令牌进行登录:

    您需要包含以下脚本:https://ajax.aspnetcdn.com/ajax/mobileservices/MobileServices.Web-1.2.8.min.js

    然后,在使用ADAL.JS获取令牌后,您可以使用它来登录并获取移动服务身份验证令牌:

    var appUrl = 'https://foobar.azure-mobile.net'
      , appKey = 'zumo key' // found on the dashboard of the mobile service
      , client = new WindowsAzure.MobileServiceClient(appUrl, appKey);
    
    // ...
    var token = this.getAADToken(ZUMOAuthenticationProvider.Config().url);
    
    client
      .login('aad', { 'access_token': token })
      .then(function() {
        // client.currentUser.mobileServiceAuthenticationToken
      });
    

    然后,此令牌需要包含在后续的移动服务API请求中:

    var config = {
      headers: {
        'X-ZUMO-AUTH': client.currentUser.mobileServiceAuthenticationToken
      }
    }
    
    $http
      .get(appUrl + '/some/path', config)
      .then(function (r) {
         console.log(r);
      });
    
  • 2

    POST可能返回401,因为AAD令牌的受众不正确 . 移动服务期望这是其/ login / aad endpoints ,但我怀疑您发送的令牌实际上是作用于您正在呼叫的网站 . 委派的访问权限只表示您可以从站点获取令牌并将其转换为移动服务的令牌 . 它不会改变已发布令牌本身的性质 .

    因此,最好的建议是确保您已登录移动服务受众,或执行委派的访问流程 . 不幸的是,后者似乎没有太多的样本unless using ADAL.NET

    一种解决方法是在移动服务上设置MS_AadAudience应用程序设置以匹配您的网站 . 只有在站点和移动服务存在于应用程序的同一逻辑安全边界内时,才应执行此操作 . 那是的,此时可以登录您网站的任何内容都可以访问移动服务 . 总的来说,更好的方法是获得移动服务的访问令牌 .

相关问题