zoukankan      html  css  js  c++  java
  • Azure AAD 验证方式

    总结一下最近项目上使用azure 遇到的问题。

    azure functions 使用 aad auoth 2.0 身份证书身份认证。从国外一个博客上学到的知识。信息量非常大,博客中介绍了如何使用key vault 创建证书。

    先简单介绍一下原理,然后再讲一下容易出错的细节

    azure funcation: funcApi; 对应的 app叫 funApiApp ,配置一个客户端app 叫 clientApp.

    我们把前期工作先做好:

    1 创建azure funcation funcAPI

    2.在azure activity directory 中注册两个APP。funApiApp 和clientApp。

    3.在key vault 中创建证书。并将CER格式的证书下载。

    1 配置 azure function 使用 AAD身份认证,使用Express模式,选择前期工作中创建的APP:funApiApp 

    2 配置APP:funApiApp ,编辑mainfest: 添加appRoles 将保存

    "appRoles": [
    		{
    			"allowedMemberTypes": [
    				"Application"
    			],
    			"description": "Accesss the service-api",
    			"displayName": "service-api",
    			"id": "d5deb0a5-0d04-4740-a48d-d6b92c3578db",
    			"isEnabled": true,
    			"lang": null,
    			"origin": "Application",
    			"value": "service-api"
    		},
    		{
    			"allowedMemberTypes": [
    				"Application"
    			],
    			"description": "Accesss the access_as_applicaton",
    			"displayName": "access_as_application",
    			"id": "d3deb0a5-0d04-4740-a48d-d6b92c3578db",
    			"isEnabled": true,
    			"lang": null,
    			"origin": "Application",
    			"value": "access_as_application"
    		}
    	],
    

      

    3 配置clientAPP,上传在前期工作中3步的证书上传

     4 添加权限,添加对funcApiApp的权限

     5。获取funapiApp的 appid.及刚才的URL

    6.获取clientapp的clientid

    7。配置key vault的访问权限,可以在代码获取证书文件。

    Get started with Key Vault certificates | Microsoft Docs

     8 获取证书,获取token,调用API代码如下 

     public static async Task Test()
            {
    
                
                // Use Key Vault to get certificate
                var azureServiceTokenProvider = new AzureServiceTokenProvider();
    
                // Get the certificate from Key Vault
                var identifier = Environment.GetEnvironmentVariable("KeyVaultCertificateName");//Environment.GetEnvironmentVariable("ClientCertificates:0:KeyVaultCertificateName"];
                var cert = await GetCertificateAsync(identifier);
    
                var scope =Environment.GetEnvironmentVariable("ScopeForAccessToken");
                var authority = $"{Environment.GetEnvironmentVariable("Instance")}{Environment.GetEnvironmentVariable("TenantId")}";
    
                // client credentials flows, get access token
                IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
                         .Create(Environment.GetEnvironmentVariable("ClientId"))
                         .WithAuthority(new Uri(authority))
                         .WithCertificate(cert)
                         .WithLogging(MyLoggingMethod, Microsoft.Identity.Client.LogLevel.Verbose,
                             enablePiiLogging: true, enableDefaultPlatformLogging: true)
                         .Build();
    
                var accessToken = await app.AcquireTokenForClient(new[] { scope }).ExecuteAsync();
    
    
                HttpClient client = new HttpClient();
    
                client.BaseAddress = new Uri(Environment.GetEnvironmentVariable("ApiBaseAddress"));
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.AccessToken);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                // use access token and get payload
                var content = new StringContent("", Encoding.UTF8, "application/json");
    
                var response = await client.PostAsync(Environment.GetEnvironmentVariable("TargetURL"), content); ;
                if (response.IsSuccessStatusCode)
                {
                    var responseContent = await response.Content.ReadAsStringAsync();
                    var data = JArray.Parse(responseContent);
    
                   //eturn data;
                }
            }
    
            private static async Task<X509Certificate2> GetCertificateAsync(string identitifier)
            {
                var vaultBaseUrl =Environment.GetEnvironmentVariable("KeyVaultUrl");
    
                // including AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID.
                var secretClient = new SecretClient(vaultUri: new Uri(vaultBaseUrl),
                       credential: new DefaultAzureCredential());
               
    
                // Create a new secret using the secret client.
                var secretName = identitifier;
                //var secretVersion = "";
                KeyVaultSecret secret = await secretClient.GetSecretAsync(secretName);
    
                var privateKeyBytes = Convert.FromBase64String(secret.Value);
    
                var certificateWithPrivateKey = new X509Certificate2(privateKeyBytes,
                    (string)null,
                    X509KeyStorageFlags.MachineKeySet);
    
                return certificateWithPrivateKey;
            }
    
            static void MyLoggingMethod(Microsoft.Identity.Client.LogLevel level, string message, bool containsPii)
            {
                _log.LogInformation($"MSAL {level} {containsPii} {message}");
            }
    

     

    PS:获取key vault 的配置需要配置环境变量

    在项目中设置环境变量,
    // Create a new certificate client using the default credential from Azure.Identity using environment variables previously set, // including AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID. var client = new CertificateClient(vaultUri: new Uri(keyVaultUrl), credential: new DefaultAzureCredential());
     

    其它配置文件:

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "ScopeForAccessToken": "http://XXXXX/.default",
        "ApiBaseAddress": "https://localhost:44390",
        "Instance": "https://login.microsoftonline.com/",
        "Domain": "damienbodhotmail.onmicrosoft.com",
        "TenantId": "XXXXX,
        "ClientId": "XXXXX",
    
    
        "SourceType": "KeyVault",
        "KeyVaultUrl": "https://XXX.vault.azure.net/",
        "KeyVaultCertificateName": "XXXX"
      }
    }
    

      

     原理图

  • 相关阅读:
    检测mysq组复制的脚本
    centos7安装NFS
    mysql组复制安装
    springboot+VUE(一)
    redis集群配置
    codevs 3139 栈练习3
    codevs 3138 栈练习2
    codevs 2622 数字序列
    codevs 1054 电梯
    codevs 1507 酒厂选址
  • 原文地址:https://www.cnblogs.com/hellohongfu/p/14393739.html
Copyright © 2011-2022 走看看