用于AzureMap的Azure Active Directory令牌

pcww981p  于 2023-02-25  发布在  其他
关注(0)|答案(1)|浏览(117)

我尝试了以下示例来实现AzureMap的Azure Active Directory令牌。

//Html
<html>
<body>
  <input type="button" onclick="LoadMapControl(this)" value="Load Map" />
  
  <div id="map"></div>
</body>
</html>

// Javascript
var map;

function LoadMapControl(elm) {
  //Only load the map if is hasn't been loaded. 
  if (!LazyMapLoader.IsLoaded()) {
    LazyMapLoader.LoadMapControl(GetMap);
  } else if (map == null) {
    GetMap();
  }

  //Hide the button
  elm.style.display = 'none';
}

function GetMap() {
  //Initialize a map instance.
  map = new atlas.Map('map', {
    view: 'Auto',

    //Add your Azure Maps subscription client ID to the map SDK.
    authOptions: {
      authType: "anonymous",
      clientId: "04ec075f-3827-4aed-9975-d56301a2d663", //Your Azure Maps account Client ID is required to access your Azure Maps account.

      getToken: function (resolve, reject, map) {
        //URL to your authentication service that retrieves an Azure Active Directory Token.
        var tokenServiceUrl = "https://azuremapscodesamples.azurewebsites.net/Common/TokenService.ashx";

        fetch(tokenServiceUrl).then(r => r.text()).then(token => resolve(token));
      }
    }
  });
}

//A reusable class that makes it easy to lazy load the Azure Maps Atlas map SDK.
var LazyMapLoader = new function () {
  var _callback = null, _isLoading = false;

  function isLoaded() {
    //Verify that the atlas namespace is loaded and that the Map class is recognized.
    return typeof (atlas) != 'undefined'
    && typeof (atlas.Map) != 'undefined';
  }

  this.LoadMapControl = function (callback) {
    var loaded = isLoaded();
    if (!_isLoading && !loaded) {
      _callback = callback;
      _isLoading = true;

      //Load the Atlas CSS Styles.
      var styles = document.createElement('link');
      styles.setAttribute('type', 'text/css');
      styles.setAttribute('rel', 'stylesheet');
      styles.setAttribute('href', 'https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css');
      document.body.appendChild(styles);

      //Load the Atlas JavaScript SDK.
      var script = document.createElement('script');
      script.setAttribute('type', 'text/javascript');
      script.setAttribute('src', 'https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js');
      document.body.appendChild(script);
      setTimeout('LazyMapLoader.__LoadCallback();', 100);
    } else if (loaded) {
      _callback();
    }
  };

  this.IsLoaded = function () {
    return isLoaded();
  };

  this.__LoadCallback = function () {
    if (isLoaded()) {
      _callback();
      _isLoading = false;
    } else {
      setTimeout('LazyMapLoader.__LoadCallback();', 100);
    }
  };
};

// Css
html,
body {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}

#map {
  width: 100%;
  height: 100%;
}

我知道我们需要加入我们的身份验证服务,而不是“https://azuremapscodesamples.azurewebsites.net/Common/TokenService.ashx“。有人知道如何在Azure门户中执行此操作吗?
TokenServiceUrl
因为它未经授权,我得到了以下错误。
Error
如果有人能解释一下如何为Azure Map实现Azure Active Directory令牌,我将不胜感激。

idfiyjo8

idfiyjo81#

您可以创建一个简单的Azure函数,或者如果使用Azure Web应用程序,则在其中添加一个简单的服务以获取令牌。
以下是我在HTTP触发器Azure函数中使用的代码,用于我的一个应用程序获取令牌(用C#编写):

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Azure.Core;
using Azure.Identity;

namespace Microsoft.GetAzureMapsToken
{
    public static class GetAzureMapsToken
    {
        /// <summary>
        /// This token provider simplifies access tokens for Azure Resources. It uses the Managed Identity of the deployed resource.
        /// For instance if this application was deployed to Azure App Service or Azure Virtual Machine, you can assign an Azure AD
        /// identity and this library will use that identity when deployed to production.
        /// </summary>
        /// <remarks>
        /// This tokenProvider will cache the token in memory, if you would like to reduce the dependency on Azure AD we recommend
        /// implementing a distributed cache combined with using the other methods available on tokenProvider.
        /// </remarks>
        private static readonly DefaultAzureCredential tokenProvider = new();

        ///A list of any domains you want to restrict access from. This is optional and a secondary security measure.
        private static readonly string[] allowed = { 
            "https://my-custom-domain.com/"
        };

        [FunctionName("GetAzureMapsToken")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req)
        {
             string referer = req.Headers["Referer"];

            if (string.IsNullOrEmpty(referer))
                return new UnauthorizedResult();

            string result = Array.Find(allowed, site => referer.StartsWith(site, StringComparison.OrdinalIgnoreCase));
            if (string.IsNullOrEmpty(result))
                return new UnauthorizedResult();

            // Managed identities for Azure resources and Azure Maps
            // For the Web SDK to authorize correctly, you still must assign Azure role based access control for the managed identity
            // https://docs.microsoft.com/en-us/azure/azure-maps/how-to-manage-authentication
            var accessToken = await tokenProvider.GetTokenAsync(
                new TokenRequestContext(new[] { "https://atlas.microsoft.com/.default" })
            );

            return new OkObjectResult(accessToken.Token);
        }
    }
}

然后我用来调用此服务的URL如下所示:

https://<My Azure function domain>.azurewebsites.net/api/GetAzureMapsToken

为了使该功能能够访问你的AzureMap帐户,你需要向AzureMap帐户“添加角色分配”。具体操作如下:
1.进入Azure门户,转到您的AzureMap帐户资源。
1.选择“访问控制(IAM)"。
1.单击“角色分配”。
1.单击“添加”,然后单击“添加角色分配”。

  • 选择一个角色类型。您很可能需要一个读者类型角色。
  • “Reader”提供对所有Azure Maps API的访问,包括Azure Maps CreatorMap平台的数据API(室内Map和您上传的自定义数据)。
  • “AzureMap数据读取器”仅提供对AzureMap创建者平台的访问。
  • “Azure Maps搜索和呈现数据读取器”通过Azure Maps Creator平台提供对所有的访问。在大多数情况下,你需要此角色或“读取器”角色。
  • 单击“下一步”,然后在“成员”下选择“用户、组或服务主体”。
  • 然后按“选择成员”并搜索您的azure功能。选择它并按“下一步”,然后查看并分配。

这可能需要5分钟的时间在系统中传播,所以如果它不能马上工作,不要紧张。
最后,请确保使用AzureMap帐户中的值更新JavaScript代码中的clientId(您可以在门户中AzureMap帐户资源的“身份验证”部分下找到该值)。

相关问题