7

請求の使用状況とレートカードの詳細を取得するために Azure REST API を使用しています。AcquireToken()メソッドを使用してトークンを取得するには、最初にクライアント IDのみを使用し、ログイン ウィンドウでユーザー資格情報を要求しました。

しかし、私はNon-Interactive Approachを探しているので、 Client IdClient Secret Keyを渡したClient Credentialsを使用しました。

しかし、「リモートサーバーがエラー401 Unauthorizedを返します」と表示されます

エラーを詳しく調べてみると、 「アクセストークンは間違ったオーディエンスまたはリソースからのものです」というエラーが発生することがわかりました

ユーザーの操作なしで API にアクセスできるソリューションを教えてください。

前もって感謝します。

これが私のコードです:

{
    string token = GetOAuthTokenFromAAD();
    string requestURL = String.Format("{0}/{1}/{2}/{3}",
                   ConfigurationManager.AppSettings["ARMBillingServiceURL"],
                   "subscriptions",
                   ConfigurationManager.AppSettings["SubscriptionID"],
                   "providers/Microsoft.Commerce/RateCard?api-version=2015-06-01-preview&$filter=OfferDurableId eq 'MS-AZR-*****' and Currency eq 'INR' and Locale eq 'en-IN' and RegionInfo eq 'IN'");

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestURL);

    request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
    request.ContentType = "application/json";
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    Console.WriteLine(String.Format("RateCard service response status: {0}", response.StatusDescription));
}

public static string GetOAuthTokenFromAAD()
{
      AuthenticationContext authenticationContext = new AuthenticationContext(string.Format("{0}/{1}",ConfigurationManager.AppSettings["ADALServiceURL"], ConfigurationManager.AppSettings["TenantDomain"]));

      AuthenticationResult result = null;
      ClientCredential uc = new ClientCredential(Client_Id, Secret_Key);
      try
      {
           result = authenticationContext.AcquireToken("https://management.core.windows.net/", uc);
      } 
      return result.AccessToken;
}

//App Config File
<add key="ADALServiceURL" value="https://login.microsoftonline.com" />
<add key="ADALRedirectURL" value="http://*****-authentication.cloudapp.net" />
<add key="ARMBillingServiceURL" value="https://management.core.windows.net" />
<add key="TenantDomain" value="********.onmicrosoft.com" />
<add key="SubscriptionID" value="*******-****-****-****-********" />
<add key="ClientId" value="*******-****-****-****-********" />
4

1 に答える 1

1

更新: これらのメソッドをReusable Authentication Helper Class Libraryとして提供しました。このリンクで同じものを見つけることができます: Azure Authentication - Authenticating any Azure API Request in your Application

方法 1:パスワード アプローチを非対話的に使用するには、最初に以下の投稿のセクション「パスワードによる認証 - PowerShell」に従う必要があります: ARM を使用したサービス プリンシパルの認証

次に、以下のコード スニペットを使用してトークンをフェッチします。

var authenticationContext = new AuthenticationContext(String.Format("{0}/{1}",
                                                                ConfigurationManager.AppSettings["ADALServiceURL"],
                                                                ConfigurationManager.AppSettings["TenantDomain"]));
        var credential = new ClientCredential(clientId: "11a11111-11a1-111a-a111-1afeda2bca1a", clientSecret: "passwordhere");
        var result = authenticationContext.AcquireToken(resource: "https://management.core.windows.net/", clientCredential: credential);

        if (result == null)
        {
            throw new InvalidOperationException("Failed to obtain the JWT token");
        }

        string token = result.AccessToken;

        return token;

または (方法 2)、証明書による方法を使用することもできます。その場合は、上記と同じリンクを使用しますが、そのリンクから「証明書で認証 - PowerShell」セクションに従ってください。次に、以下のコード スニペットを使用して、トークンを非対話的にフェッチします。

 var subscriptionId = "1a11aa11-5c9b-4c94-b875-b7b55af5d316";
        string tenant = "1a11111a-5713-4b00-a1c3-88da50be3ace";
        string clientId = "aa11a111-1050-4892-a2d8-4747441be14d";

        var authContext = new AuthenticationContext(string.Format("https://login.windows.net/{0}", tenant));

        X509Certificate2 cert = null;
        X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        string certName = "MyCert01";

        try
        {
            store.Open(OpenFlags.ReadOnly);
            var certCollection = store.Certificates;
            var certs = certCollection.Find(X509FindType.FindBySubjectName, certName, false);
            //var certs = certCollection.Find(X509FindType.FindBySerialNumber, "E144928868B609D35F72", false);
            if (certs == null || certs.Count <= 0)
            {
                throw new Exception("Certificate " + certName + " not found.");
            }
            cert = certs[0];
        }
        finally
        {
            store.Close();
        }

        var certCred = new ClientAssertionCertificate(clientId, cert);
        var token = authContext.AcquireToken("https://management.core.windows.net/", certCred);
        var creds = new TokenCloudCredentials(subscriptionId, token.AccessToken);
        //var client = new ResourceManagementClient(creds); 
        return token.AccessToken;
于 2016-03-21T19:59:25.760 に答える