1

Azure Maps Authentication and Authorization

 2 years ago
source link: https://techcommunity.microsoft.com/t5/azure-maps-blog/azure-maps-web-application-authentication-the-right-way/ba-p/3600082
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Introduction

One of the requirements when building a business application, which may give access to private business data, is that only authenticated employees or agents be able to see that data. So how can you use Azure Maps in combination with authentication and authorization to ensure only the people that should be allowed have access?

Our Azure Maps docs describe in detail many different authentication scenarios but the complexity can make it seem difficult to implement. This blog post will focus on our most requested authentication scenario for Azure Maps. Use the following step by step guidance to have a .NET web application embedded Azure Maps web control where only authenticated users can see the website and use the map.

Prerequisites

In this article, we use the following resources:

  •  .NET 6.0 and the C# programming language. You can download, and install the latest version of .NET from https://dot.net/
  • To make it easier to edit source code, we also recommend installing Visual Studio Code Edition, which is a lightweight but powerful source code editor from Microsoft https://code.visualstudio.com/
  • Before you can use Azure Maps, you will need to sign up for a free Azure subscription, at https://azure.microsoft.com/free
  • And finally, install the Azure Command-Line Interface (CLI) tools. Read here How to install the Azure CLI.

Step 1. Basic Web Application with Azure Maps

Let's start with a basic .NET web application and Azure Maps. No authentication yet, that will come in the next paragraph. This first step will use an Azure Maps Key (a ‘shared Key authentication’ or subscription key) that should not be used in production. An Azure Maps Key has complete control over your Azure Maps resource. In the next paragraph, we will remove this key and replace this with managed identities for Azure resources.

Create a folder, we called ours AzureMapsDemo, and add a new web application to it. Then open the newly created web application in Visual Studio Code. Start PowerShell (or any other terminal) and enter the following commands:

mkdir AzureMapsDemo
cd .\AzureMapsDemo
dotnet new mvc
code .

Next add the Azure Maps web control to the Home view, open the file Views/Home/index.cshtml, and replace all the content with:

@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Azure Maps</h1>
    <p>Learn about <a href="https://docs.microsoft.com/azure/azure-maps/">building Azure Maps apps with ASP.NET Core</a>.</p>
</div>

<div id="myMap" style="width:100%;min-width:290px;height:600px;"></div>

@section Scripts
{
    <link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css" />
    <script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js"></script>

    <script>
        var map;

        // Initialize a map instance.
        map = new atlas.Map('myMap', {
            center: [-122.33, 47.6],
            zoom: 12,
            style: 'satellite_road_labels',
            view: 'Auto',

            // Add authentication details for connecting to Azure Maps.
            authOptions: {
                authType: 'subscriptionKey',
                subscriptionKey: '[YOUR_AZURE_MAPS_KEY]'
            }
        });

        // Wait until the map resources are ready.
        map.events.add('ready', function() {
            // Add your post map load code here.
        });
    </script>
}

As you can see, we need a subscription key for Azure Maps before starting the web application and using the map. In the next step, we are creating an Azure resource group and adding a new Azure Maps Account. Then we extract the Azure Maps Primary Key from this Azure Maps Account, which we use in our Home view.

1.1 Login into your Azure subscription and save the Azure subscription Id, we need this for later.

az login

1.2 (Optional) Select the subscription where you would like to create the Azure Maps Account.

az account set --subscription "<your subscription>"

1.3 Create a resource group, and change the name and the location for your needs.

az group create -l westeurope -n rg-azuremaps

1.4 Create the Azure Maps Account, and accept the terms and conditions. Save the uniqueId for later.

az maps account create -n map-azuremaps -g rg-azuremaps -s "G2" --kind "Gen2"

1.5 Now we can extract the Azure Maps Primary Key and add it to the Home view in our web application.

az maps account keys list -n map-azuremaps -g rg-azuremaps

1.6 Replace the [YOUR_AZURE_MAPS_KEY] in the file Views/Home/index.cshtml with the Azure Maps Primary Key we just listed in step 1.5.

1.7 Now we can run and test our AzureMapsDemo web application.

dotnet run​
az appservice plan create -g rg-azuremaps -n plan-azuremaps -l westeurope

az webapp create -g rg-azuremaps -p plan-azuremaps -n web-azuremaps -r "dotnet:6"
az webapp identity assign -n web-azuremaps -g rg-azuremaps
az role assignment create --assignee "[PRINCIPAL_ID]" --role "Azure Maps Data Reader" --scope "/subscriptions/[YOUR_AZURE_SUBSCRIPTION_ID]/resourceGroups/rg-azuremaps/providers/Microsoft.Maps/accounts/map-azuremaps"
dotnet add package Azure.Identity
using Azure.Core;
using Azure.Identity;
using Microsoft.AspNetCore.Mvc;

namespace AzureMapsDemo.Controllers;

public class ApiController : Controller
{
    private static readonly DefaultAzureCredential tokenProvider = new();

    public async Task<IActionResult> GetAzureMapsToken()
    {
        var accessToken = await tokenProvider.GetTokenAsync(
            new TokenRequestContext(new[] { "https://atlas.microsoft.com/.default" })
        );

        return new OkObjectResult(accessToken.Token);
    }
}
// Add authentication details for connecting to Azure Maps.
authOptions: {
    // Use Azure Active Directory authentication.
    authType: 'anonymous',
    // Your Azure Maps client id for accessing your Azure Maps account.
    clientId: '[YOUR_AZUREMAPS_CLIENT_ID]',
    getToken: function(resolve, reject, map) {
        // URL to your authentication service that retrieves
        // an Azure Active Directory Token.
        var tokenServiceUrl = "/api/GetAzureMapsToken";

        fetch(tokenServiceUrl).then(r => r.text()).then(token => resolve(token));
    }
}
az maps account show -n map-azuremaps -g rg-azuremaps
dotnet publish --configuration Release

Compress-Archive -Path bin\Release\net6.0\publish\* -DestinationPath release1.zip
az webapp deployment source config-zip -g rg-azuremaps -n web-azuremaps --src release1.zip
az ad app create --display-name "Azure Maps Demo App" --web-redirect-uris https://web-azuremaps.azurewebsites.net/signin-oidc --enable-access-token-issuance true --enable-id-token-issuance true --sign-in-audience AzureADMyOrg
dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Identity.Web.UI
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
using Azure.Core;
using Azure.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;

namespace AzureMapsDemo.Controllers;

[Authorize]
public class ApiController : Controller
{
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
});

builder.Services.AddControllersWithViews(options =>
{
    var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
    options.Filters.Add(new AuthorizeFilter(policy));
});
builder.Services.AddRazorPages()
    .AddMicrosoftIdentityUI();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
app.MapControllers();

app.Run();
{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "[PUBLISHER_DOMAIN]",
    "TenantId": "[AAD_TENANT_ID]",
    "ClientId": "[APP_ID]",
    "CallbackPath": "/signin-oidc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}
az account tenant list
dotnet publish --configuration Release

Compress-Archive -Path bin\Release\net6.0\publish\* -DestinationPath release2.zip
az webapp deployment source config-zip -g rg-azuremaps -n web-azuremaps --src release2.zip
az maps account update -n map-azuremaps -g rg-azuremaps --disable-local-auth true -s "G2"

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK