Öğretici: Azure Uzaktan İşleme ve model depolama güvenliğini sağlama

Bu öğreticide aşağıdakilerin nasıl yapılacağını öğreneceksiniz:

  • Azure Uzaktan İşleme modellerini içeren güvenli Azure Blob Depolama
  • Azure Uzaktan İşleme örneğine erişmek için Microsoft Entra Kimliği ile kimlik doğrulaması yapın
  • Azure Uzaktan İşleme kimlik doğrulaması için Azure kimlik bilgilerini kullanma

Önkoşullar

Neden ek güvenlik gerekiyor?

Uygulamanın geçerli durumu ve Azure kaynaklarınıza erişimi şu şekilde görünür:

Initial security

Hem "AccountID + AccountKey" hem de "URL + SAS Belirteci" temelde bir kullanıcı adı ve parolayı birlikte depolar. Örneğin, "AccountID + AccountKey" kullanıma sunulduysa, bir saldırganın sizin izniniz olmadan ARR kaynaklarınızı kullanması sizin sorumluluğunuzda olacaktır.

Azure Blob Depolama'da içeriğinizin güvenliğini sağlama

Azure Uzaktan İşleme doğru yapılandırmayla Azure Blob Depolama içeriğine güvenli bir şekilde erişebilir. Bkz . Nasıl yapılır: Azure Uzaktan İşleme örneğinizi blob depolama hesaplarınızla yapılandırmak için depolama hesaplarını bağlama.

Bağlı blob depolama kullanırken, modelleri yüklemek için biraz farklı yöntemler kullanırsınız:

var loadModelParams = new LoadModelFromSasOptions(modelPath, modelEntity);
var task = ARRSessionService.CurrentActiveSession.Connection.LoadModelFromSasAsync(loadModelParams);

Yukarıdaki satırlarda parametreler ve oturum eyleminin sürümü kullanılır FromSas . Sas olmayan sürümlere dönüştürülmeleri gerekir:

var loadModelParams = LoadModelOptions.CreateForBlobStorage(storageAccountPath, blobName, modelPath, modelEntity);
var task = ARRSessionService.CurrentActiveSession.Connection.LoadModelAsync(loadModelParams);

RemoteRenderingCoordinator'ı, bağlı blob depolama hesabından özel bir model yüklenecek şekilde değiştirelim.

  1. Henüz yapmadıysanız, ARR örneğinize Blob Depolama örneğine erişim izni vermek için Nasıl yapılır: Bağlantı depolama hesaplarını tamamlayın.

  2. Aşağıdaki değiştirilmiş LoadModel yöntemini geçerli LoadModel yönteminin hemen altına RemoteRenderingCoordinator'a ekleyin:

    /// <summary>
    /// Loads a model from blob storage that has been linked to the ARR instance
    /// </summary>
    /// <param name="storageAccountName">The storage account name, this contains the blob containers </param>
    /// <param name="blobName">The blob container name, i.e. arroutput</param>
    /// <param name="modelPath">The relative path inside the container to the model, i.e. test/MyCustomModel.arrAsset</param>
    /// <param name="parent">The parent Transform for this remote entity</param>
    /// <param name="progress">A call back method that accepts a float progress value [0->1]</param>
    /// <returns></returns>
    public async Task<Entity> LoadModel(string storageAccountName, string blobName, string modelPath, UnityEngine.Transform parent = null, Action<float> progress = null)
    {
        //Create a root object to parent a loaded model to
        var modelEntity = ARRSessionService.CurrentActiveSession.Connection.CreateEntity();
    
        //Get the game object representation of this entity
        var modelGameObject = modelEntity.GetOrCreateGameObject(UnityCreationMode.DoNotCreateUnityComponents);
    
        //Ensure the entity will sync its transform with the server
        var sync = modelGameObject.GetComponent<RemoteEntitySyncObject>();
        sync.SyncEveryFrame = true;
    
        //Parent the new object under the defined parent
        if (parent != null)
        {
            modelGameObject.transform.SetParent(parent, false);
            modelGameObject.name = parent.name + "_Entity";
        }
    
        //Load a model that will be parented to the entity
        var loadModelParams = LoadModelOptions.CreateForBlobStorage($"{storageAccountName}.blob.core.windows.net", blobName, modelPath, modelEntity);
        var loadModelAsync = ARRSessionService.CurrentActiveSession.Connection.LoadModelAsync(loadModelParams, progress);
        var result = await loadModelAsync;
        return modelEntity;
    }
    

    Bu kod özgün LoadModel yöntemle aynıdır, ancak yöntem çağrılarının SAS sürümünü SAS olmayan sürümlerle değiştirdik.

    Ek girişler storageAccountName ve blobName bağımsız değişkenlere de eklendi. Bu yeni LoadModel yöntemini, ilk öğreticide oluşturduğumuz ilk LoadTestModel yöntemine benzer başka bir yöntemden çağırırız.

  3. Aşağıdaki yöntemi LoadTestModel'in hemen ardından RemoteRenderingCoordinator'a ekleyin

    private bool loadingLinkedCustomModel = false;
    
    [SerializeField]
    private string storageAccountName;
    public string StorageAccountName {
        get => storageAccountName.Trim();
        set => storageAccountName = value;
    }
    
    [SerializeField]
    private string blobContainerName;
    public string BlobContainerName {
        get => blobContainerName.Trim();
        set => blobContainerName = value;
    }
    
    [SerializeField]
    private string modelPath;
    public string ModelPath {
        get => modelPath.Trim();
        set => modelPath = value;
    }
    
    [ContextMenu("Load Linked Custom Model")]
    public async void LoadLinkedCustomModel()
    {
        if (CurrentCoordinatorState != RemoteRenderingState.RuntimeConnected)
        {
            Debug.LogError("Please wait for the runtime to connect before loading the test model. Try again later.");
            return;
        }
        if (loadingLinkedCustomModel)
        {
            Debug.Log("Linked Test model already loading or loaded!");
            return;
        }
        loadingLinkedCustomModel = true;
    
        // Create a parent object to use for positioning
        GameObject testParent = new GameObject("LinkedCustomModel");
        testParent.transform.position = new Vector3(0f, 0f, 3f);
    
        await LoadModel(StorageAccountName, BlobContainerName, ModelPath, testParent.transform, (progressValue) => Debug.Log($"Loading Test Model progress: {Math.Round(progressValue * 100, 2)}%"));
    }
    

    Bu kod RemoteRenderingCoordinator bileşeninize üç ek dize değişkeni ekler. Screenshot that highlights the Storage Account Name, Blob Container Name, and Model Path of the RemoteRenderingCoordinator component.

  4. Değerlerinizi RemoteRenderingCoordinator bileşenine ekleyin. Model dönüştürme için Hızlı Başlangıç'ı izledikten sonra değerleriniz şu şekilde olmalıdır:

    • Depolama Hesap Adı: Depolama hesabınızın adı, depolama hesabınız için seçtiğiniz genel olarak benzersiz ad. Hızlı başlangıçta bu arrtutorialstorage idi, değeriniz farklıdır.
    • Blob Kapsayıcı Adı: arroutput, Blob Depolama Kapsayıcısı
    • Model Yolu: arrconfig.json dosyasında tanımlanan "outputFolderPath" ve "outputAssetFileName" birleşimi. Bu, hızlı başlangıçta "outputFolderPath":"converted/robot", "outputAssetFileName": "robot.arrAsset" şeklindeydi. Bu da "converted/robot/robot.arrAsset" Model Yolu değerinin farklı olmasına neden olur.

    Bahşiş

    Conversion.ps1 betiğini "-UseContainerSas" bağımsız değişkeni olmadan çalıştırırsanız, betik SAS belirteci yerine yukarıdaki değerlerin tümünün çıkışını verir. Linked Model

  5. Şimdilik, özel modelinizin yüklenmesine yer açmak için GameObject TestModel'i kaldırın veya devre dışı bırakın.

  6. Sahneyi oynatın ve uzak bir oturuma bağlanın.

  7. RemoteRenderingCoordinator'da bağlam menüsünü açın ve Bağlı Özel Modeli Yükle'yi seçin. Load linked model

Bu adımlar, SAS belirtecini yerel uygulamadan kaldırarak uygulamanın güvenliğini artırdı.

Uygulamanın geçerli durumu ve Azure kaynaklarınıza erişimi şu şekilde görünür:

Better security

Yerel uygulamadan kaldırılacak bir "parola" daha (AccountKey) var. Bu, Microsoft Entra kimlik doğrulaması kullanılarak yapılabilir.

Microsoft Entra doğrulaması

Microsoft Entra kimlik doğrulaması, hangi kişilerin veya grupların ARR'yi daha denetimli bir şekilde kullandığını belirlemenize olanak tanır. ARR, Hesap Anahtarı kullanmak yerine Erişim Belirteçlerini kabul etmek için yerleşik destek sağlar. Erişim Belirteçleri'ni, istenen kaynağın yalnızca belirli bölümlerinin kilidini açan, zaman sınırlı, kullanıcıya özgü bir anahtar olarak düşünebilirsiniz.

RemoteRenderingCoordinator betiği, uzak oturum yönetimini yapılandırmak için kullanılan SessionConfiguration nesnesini döndüren bir yöntemi tutan ARRCredentialGetter adlı bir temsilciye sahiptir. ARRCredentialGetter'a farklı bir yöntem atayarak Azure oturum açma akışı kullanmamıza olanak tanıyarak Azure Erişim Belirteci içeren bir SessionConfiguration nesnesi oluşturabiliriz. Bu Erişim Belirteci, oturum açmakta olan kullanıcıya özgü olacaktır.

  1. Yeni bir Microsoft Entra uygulaması kaydetmeyi ve ARR örneğinize erişimi yapılandırmayı içeren Nasıl Yapılır: Kimlik doğrulamasını yapılandırma - Dağıtılan uygulamalar için kimlik doğrulaması makalesini izleyin.

  2. Yeni Microsoft Entra uygulamasını yapılandırdıktan sonra, Microsoft Entra uygulamanızın aşağıdaki görüntüler gibi göründüğünü denetleyin:

    Microsoft Entra Uygulaması -> Kimlik DoğrulamasıApp authentication

    Microsoft Entra Uygulaması -> API İzinleriApp APIs

  3. Uzaktan İşleme hesabınızı yapılandırdıktan sonra yapılandırmanızın aşağıdaki görüntüye benzer olup olmadığını denetleyin:

    ARR -> AccessControl (IAM)ARR Role

    Dekont

    Sahip rolü, istemci uygulaması aracılığıyla oturumları yönetmek için yeterli değildir. Oturumları yönetme yeteneği vermek istediğiniz her kullanıcı için Uzaktan İşleme İstemcisi rolünü sağlamanız gerekir. Oturumları yönetmek ve modelleri dönüştürmek istediğiniz her kullanıcı için Uzaktan İşleme Yönetici istrator rolünü sağlamanız gerekir.

Azure'daki işlerinizi yerine getirmek için kodunuzun ARR hizmetine bağlanma şeklini değiştirmemiz gerekiyor. Bunu, yeni bir SessionConfiguration nesnesi döndüren BaseARRAuthentication örneğini uygulayarak yaparız. Bu durumda hesap bilgileri Azure Erişim Belirteci ile yapılandırılır.

  1. AADAuthentication adlı yeni bir betik oluşturun ve kodunu aşağıdakilerle değiştirin:

    // Copyright (c) Microsoft Corporation. All rights reserved.
    // Licensed under the MIT License. See LICENSE in the project root for license information.
    
    using Microsoft.Azure.RemoteRendering;
    using Microsoft.Identity.Client;
    using System;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using UnityEngine;
    
    public class AADAuthentication : BaseARRAuthentication
    {
        [SerializeField]
        private string activeDirectoryApplicationClientID;
        public string ActiveDirectoryApplicationClientID
        {
            get => activeDirectoryApplicationClientID.Trim();
            set => activeDirectoryApplicationClientID = value;
        }
    
        [SerializeField]
        private string azureTenantID;
        public string AzureTenantID
        {
            get => azureTenantID.Trim();
            set => azureTenantID = value;
        }
    
        [SerializeField]
        private string azureRemoteRenderingDomain;
        public string AzureRemoteRenderingDomain
        {
            get => azureRemoteRenderingDomain.Trim();
            set => azureRemoteRenderingDomain = value;
        }
    
        [SerializeField]
        private string azureRemoteRenderingAccountID;
        public string AzureRemoteRenderingAccountID
        {
            get => azureRemoteRenderingAccountID.Trim();
            set => azureRemoteRenderingAccountID = value;
        }
    
        [SerializeField]
        private string azureRemoteRenderingAccountDomain;
        public string AzureRemoteRenderingAccountDomain
        {
            get => azureRemoteRenderingAccountDomain.Trim();
            set => azureRemoteRenderingAccountDomain = value;
        }    
    
        public override event Action<string> AuthenticationInstructions;
    
        string authority => "https://login.microsoftonline.com/" + AzureTenantID;
    
        string redirect_uri = "https://login.microsoftonline.com/common/oauth2/nativeclient";
    
        string[] scopes => new string[] { "https://sts.mixedreality.azure.com//.default" };
    
        public void OnEnable()
        {
            RemoteRenderingCoordinator.ARRCredentialGetter = GetARRCredentials;
            this.gameObject.AddComponent<ExecuteOnUnityThread>();
        }
    
        public async override Task<SessionConfiguration> GetARRCredentials()
        {
            var result = await TryLogin();
            if (result != null)
            {
                Debug.Log("Account signin successful " + result.Account.Username);
    
                var AD_Token = result.AccessToken;
    
                return await Task.FromResult(new SessionConfiguration(AzureRemoteRenderingAccountDomain, AzureRemoteRenderingDomain, AzureRemoteRenderingAccountID, "", AD_Token, ""));
            }
            else
            {
                Debug.LogError("Error logging in");
            }
            return default;
        }
    
        private Task DeviceCodeReturned(DeviceCodeResult deviceCodeDetails)
        {
            //Since everything in this task can happen on a different thread, invoke responses on the main Unity thread
            ExecuteOnUnityThread.Enqueue(() =>
            {
                // Display instructions to the user for how to authenticate in the browser
                Debug.Log(deviceCodeDetails.Message);
                AuthenticationInstructions?.Invoke(deviceCodeDetails.Message);
            });
    
            return Task.FromResult(0);
        }
    
        public override async Task<AuthenticationResult> TryLogin()
        {
            var clientApplication = PublicClientApplicationBuilder.Create(ActiveDirectoryApplicationClientID).WithAuthority(authority).WithRedirectUri(redirect_uri).Build();
            AuthenticationResult result = null;
            try
            {
                var accounts = await clientApplication.GetAccountsAsync();
    
                if (accounts.Any())
                {
                    result = await clientApplication.AcquireTokenSilent(scopes, accounts.First()).ExecuteAsync();
    
                    return result;
                }
                else
                {
                    try
                    {
                        result = await clientApplication.AcquireTokenWithDeviceCode(scopes, DeviceCodeReturned).ExecuteAsync(CancellationToken.None);
                        return result;
                    }
                    catch (MsalUiRequiredException ex)
                    {
                        Debug.LogError("MsalUiRequiredException");
                        Debug.LogException(ex);
                    }
                    catch (MsalServiceException ex)
                    {
                        Debug.LogError("MsalServiceException");
                        Debug.LogException(ex);
                    }
                    catch (MsalClientException ex)
                    {
                        Debug.LogError("MsalClientException");
                        Debug.LogException(ex);
                        // Mitigation: Use interactive authentication
                    }
                    catch (Exception ex)
                    {
                        Debug.LogError("Exception");
                        Debug.LogException(ex);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogError("GetAccountsAsync");
                Debug.LogException(ex);
            }
    
            return null;
        }
    }
    

Dekont

Bu kod hiçbir şekilde tamamlanmaz ve ticari bir uygulama için hazır değildir. Örneğin, en azından oturumu kapatma özelliğini de eklemek isteyebilirsiniz. Bu, istemci uygulaması tarafından sağlanan yöntem kullanılarak Task RemoveAsync(IAccount account) yapılabilir. Bu kod yalnızca öğretici kullanımına yöneliktir; uygulamanız uygulamanıza özel olacaktır.

Kod ilk olarak AquireTokenSilent kullanarak belirteci sessizce almaya çalışır. Kullanıcı daha önce bu uygulamanın kimliğini doğruladıysa bu başarılı olur. Başarılı olmazsa daha kullanıcı odaklı bir stratejiye geçin.

Bu kod için, erişim belirteci almak için cihaz kodu akışını kullanıyoruz. Bu akış, kullanıcının bir bilgisayarda veya mobil cihazda Azure hesabında oturum açmasını ve elde edilen belirtecin HoloLens uygulamasına geri gönderilmesini sağlar.

Bu sınıfın ARR açısından en önemli bölümü şu çizgidir:

return await Task.FromResult(new SessionConfiguration(AzureRemoteRenderingAccountDomain, AzureRemoteRenderingDomain, AzureRemoteRenderingAccountID, "", AD_Token, ""));

Burada uzaktan işleme etki alanı, hesap kimliği, hesap etki alanı ve erişim belirteci kullanarak yeni bir SessionConfiguration nesnesi oluşturacağız. Bu belirteç daha sonra ARR hizmeti tarafından kullanıcı daha önce yapılandırılmış rol tabanlı izinlere göre yetkilendirildiği sürece uzaktan işleme oturumlarını sorgulamak, oluşturmak ve birleştirmek için kullanılır.

Bu değişiklikle, uygulamanın geçerli durumu ve Azure kaynaklarınıza erişimi şöyle görünür:

Even better security

Kullanıcı Kimlik Bilgileri cihazda depolanmadığından (veya bu durumda cihaza girildiğinde bile), maruz kalma riski düşüktür. Artık cihaz, Blob Depolama erişmek için erişim denetimini (IAM) kullanan ARR'ye erişmek için kullanıcıya özgü, zaman sınırlı bir Erişim Belirteci kullanıyor. Bu iki adım kaynak koddan "parolaları" kaldırdı ve güvenliği önemli ölçüde artırdı. Ancak, bu kullanılabilir en fazla güvenlik değildir, modelin ve oturum yönetiminin bir web hizmetine taşınması güvenliği daha da artırır. Ticari Hazırlık bölümünde ek güvenlik konuları ele alınmalıdır.

Microsoft Entra kimlik doğrulamasını test etme

Unity Düzenleyicisi'nde, Microsoft Entra kimlik doğrulaması etkin olduğunda, uygulamayı her başlattığınızda kimlik doğrulaması yapmanız gerekir. Cihazda kimlik doğrulama adımı ilk kez gerçekleşir ve yalnızca belirtecin süresi dolduğunda veya geçersiz kılındığında yeniden gereklidir.

  1. Microsoft Entra kimlik doğrulama bileşenini RemoteRenderingCoordinator GameObject'e ekleyin.

    Microsoft Entra auth component

Dekont

ARR örnekleri deposundan tamamlanmış projeyi kullanıyorsanız, başlığının yanındaki onay kutusuna tıklayarak Microsoft Entra kimlik doğrulama bileşenini etkinleştirdiğinizden emin olun.

  1. İstemci Kimliği ve Kiracı Kimliği değerlerini doldurun. Bu değerler Uygulama Kaydınızın Genel Bakış Sayfasında bulunabilir:

    • Active Directory Uygulama İstemcisi Kimliği, Microsoft Entra uygulama kaydınızda bulunan Uygulama (istemci) kimliğidir (aşağıdaki resme bakın).
    • Azure Kiracı Kimliği, Microsoft Entra uygulama kaydınızda bulunan Dizin (kiracı) kimliğidir (aşağıdaki resme bakın).
    • Azure Uzaktan İşleme Etki Alanı, RemoteRenderingCoordinator'ın Uzaktan İşleme Etki Alanı'nda kullandığınız etki alanıyla aynıdır.
    • Azure Uzaktan İşleme Hesap Kimliği, RemoteRenderingCoordinator için kullandığınız Hesap kimliğiyle aynıdır.
    • Azure Uzaktan İşleme Hesabı Etki Alanı, RemoteRenderingCoordinator'da kullandığınız Hesap Etki Alanı ile aynıdır.

    Screenshot that highlights the Application (client) ID and Directory (tenant) ID.

  2. Unity Düzenleyicisi'nde Yürüt'e basın ve oturumu çalıştırmayı onaylayın. Microsoft Entra kimlik doğrulama bileşeni bir görünüm denetleyicisine sahip olduğundan, oturum yetkilendirme kalıcı panelinden sonra bir istem görüntülemek için otomatik olarak bağlanmıştır.

  3. AppMenu'nun sağındaki panelde bulunan yönergeleri izleyin. Şuna benzer bir şey görmeniz gerekir: Illustration that shows the instruction panel that appears to the right of the AppMenu.

    Sağlanan kodu ikincil cihazınıza (veya aynı cihazdaki tarayıcıya) girdikten ve kimlik bilgilerinizi kullanarak oturum açtıktan sonra, istekte bulunan uygulamaya, bu durumda Unity Düzenleyicisi'ne bir Erişim Belirteci döndürülür.

Bu noktadan sonra, uygulamadaki her şey normal şekilde devam etmelidir. Aşamalarda beklendiği gibi ilerlemiyorsanız Unity Konsolu'na herhangi bir hata olup olmadığını denetleyin.

Cihaza derleme

MSAL kullanarak cihaza bir uygulama oluşturuyorsanız projenizin Varlıklar klasörüne bir dosya eklemeniz gerekir. Bu, derleyicinin Öğretici Varlıkları'nda yer alan Microsoft.Identity.Client.dll dosyasını kullanarak uygulamayı doğru şekilde derlemesine yardımcı olur.

  1. Assets'te link.xml adlı yeni bir dosya ekleme

  2. aşağıdakini dosyasına ekleyin:

    <linker>
        <assembly fullname="Microsoft.Identity.Client" preserve="all"/>
        <assembly fullname="System.Runtime.Serialization" preserve="all"/>
        <assembly fullname="System.Core">
            <type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" />
        </assembly>
    </linker>
    
  3. Değişiklikleri kaydedin

Hızlı Başlangıç: Unity örneğini HoloLens'e dağıtma - HoloLens'e derlemek için örnek Projeyi derleme bölümünde bulunan adımları izleyin.

Sonraki adımlar

Bu öğretici kümesinin geri kalanı, Azure Uzaktan İşleme kullanan üretime hazır bir uygulama oluşturmaya yönelik kavramsal makaleler içerir.