Azure - 验证服务管理请求

时间:2017-02-08 10:16:07

标签: c# sql .net azure azure-sql-database

我需要执行一些Azure SQL操作。我有一个Azure AD本机应用程序。我在下面的文章中使用第一种方法来获取令牌。

https://msdn.microsoft.com/en-us/library/azure/ee460782.aspx

现在关注this文章,我使用上述令牌执行数据库操作。

static void HttpPost(string sourceDb, string targetDb, string pointInTime)
        {
            var client = new HttpClient();
            string uri = "https://management.core.windows.net:8443/" + AzureSubscriptionId + "/services/sqlservers/servers/" + AzureSqlServerName + "/restoredatabaseoperations";
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
            request.Headers.Add("Authorization", "Bearer " + accessToken);
            request.Headers.Add("x-ms-version", "2012-03-01");

            string payload = File.ReadAllText("Resources\\Backup.xml");
            payload = payload.Replace("$SourceDb", sourceDb);
            payload = payload.Replace("$TargetDb", targetDb);
            payload = payload.Replace("$PointInTime", pointInTime);
            request.Content = new StringContent(payload, Encoding.UTF8, "application/xml");

            HttpResponseMessage response = client.SendAsync(request).GetAwaiter().GetResult();
            if (response.Content != null)
            {
                string ss = response.Content.ReadAsStringAsync().Result;
            }
        }

但我收到的错误是:

"<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Code>AuthenticationFailed</Code><Message>A security token exception occured for the received JWT token.</Message></Error>"

2 个答案:

答案 0 :(得分:1)

根据您提到的Create Database Restore Request (Classic) REST API,此命令用于经典部署模型。我们应该使用新的REST API,并在您提到的文档中提到它。

  

您应该使用此处的较新Resource Manager based REST API命令。

我们可以使用ARM REST Create or Update DataBase API。关于如何获取令牌,我们需要注册AD App并将角色分配给应用程序,更多信息请参考official document。我从fiddler发送http请求,它对我来说正常。标题和正文信息请参阅屏幕截图。

enter image description here

enter image description here

身体信息:

{
  "properties": {
    "edition": "Standard",
    "requestedServiceObjectiveName": "S1",
    "sourceDatabaseId": "/subscriptions/{your subscriptionId}/resourceGroups/{ResourceGroup}/providers/Microsoft.Sql/servers/{servername}/databases/sourcedatabasename",
    "createMode": "PointInTimeRestore",
    "restorePointInTime": "2017-02-09T10:28:20.21+08:00" //source database restorePointTime
  },
  "location": "East Asia",
  "tags": {}
}

我们也可以使用Microsoft Azure SQL Management Library for .NET。    SqlMgmtClient.Databases.CreateOrUpdate(resourceGroupName, serverName, databaseName, DatabaseCreateOrUpdateParameters);

我们可以参考tutorial开始使用。我做了一个演示。更多细节请参考以下步骤

1.创建一个控制台应用程序并安装所需的库(详细信息请参阅tutorial

2.注册申请后,我们可以获得tenantId,applicationId, SecretKey,然后使用subscriptionId获取身份验证令牌。

3.使用令牌

创建SqlManagementClient对象
var _sqlMgmtClient = new SqlManagementClient(new TokenCloudCredentials(_subscriptionId, _token.AccessToken));

4.根据我们的要求创建DatabaseCreateOrUpdateParameters。 从源数据库中获取还原数据库,例如:

 CreateMode = DatabaseCreateMode.PointInTimeRestore, //craete mode from pointtimerestore
 Edition = databaseEdition,
 SourceDatabaseId = "/subscriptions/subscriptionId/resourceGroups/groupname/providers/Microsoft.Sql/servers/AzureSQlname/databases/databaseName", //source database Id
 RestorePointInTime  = DateTime.Parse("2017-02-09T02:28:20.21Z"), //resore point Time
 RequestedServiceObjectiveName = "S1"
  1. 运行演示并从门户网站查看。

    enter image description here

    enter image description here

  2. democode:

           static void Main(string[] args)
            {
                _token = GetToken(_tenantId, _applicationId, _applicationSecret);
                Console.WriteLine("Token acquired. Expires on:" + _token.ExpiresOn);
                // Instantiate management clients:
                _resourceMgmtClient = new ResourceManagementClient(new Microsoft.Rest.TokenCredentials(_token.AccessToken));
                _sqlMgmtClient = new SqlManagementClient(new TokenCloudCredentials(_subscriptionId, _token.AccessToken));
                DatabaseCreateOrUpdateResponse dbr = CreateOrUpdateDatabase(_sqlMgmtClient, _resourceGroupName, _serverName, _databaseName, _databaseEdition, _databasePerfLevel);
                Console.WriteLine("Database: " + dbr.Database.Id);
            }
            private static AuthenticationResult GetToken(string tenantId, string applicationId, string applicationSecret)
            {
                AuthenticationContext authContext = new AuthenticationContext("https://login.windows.net/" + tenantId);
                _token = authContext.AcquireToken("https://management.core.windows.net/", new ClientCredential(applicationId, applicationSecret));
                return _token;
            }
            static DatabaseCreateOrUpdateResponse CreateOrUpdateDatabase(SqlManagementClient sqlMgmtClient, string resourceGroupName, string serverName, string databaseName, string databaseEdition, string databasePerfLevel)
            {
                // Retrieve the server that will host this database
                Server currentServer = sqlMgmtClient.Servers.Get(resourceGroupName, serverName).Server;
    
                // Create a database: configure create or update parameters and properties explicitly
                DatabaseCreateOrUpdateParameters newDatabaseParameters = new DatabaseCreateOrUpdateParameters()
                {
                    Location = currentServer.Location,
                    Properties = new DatabaseCreateOrUpdateProperties
                    {
                        CreateMode = DatabaseCreateMode.PointInTimeRestore,
                        Edition = databaseEdition,
                        SourceDatabaseId = "/subscriptions/subscriptionId/resourceGroups/tomnewgroup/providers/Microsoft.Sql/servers/tomsunsqltest/databases/sourceDatabaseName",
                        RestorePointInTime  = DateTime.Parse("2017-02-09T02:28:20.21Z"),//Restore Point time
                        RequestedServiceObjectiveName = databasePerfLevel
                    }
                };
    
                DatabaseCreateOrUpdateResponse dbResponse = sqlMgmtClient.Databases.CreateOrUpdate(resourceGroupName, serverName, databaseName, newDatabaseParameters);
                return dbResponse;
            }
    

    packages.config文件:

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="Hyak.Common" version="1.0.2" targetFramework="net462" />
      <package id="Microsoft.Azure.Common" version="2.1.0" targetFramework="net462" />
      <package id="Microsoft.Azure.Common.Authentication" version="1.7.0-preview" targetFramework="net462" />
      <package id="Microsoft.Azure.Common.Dependencies" version="1.0.0" targetFramework="net462" />
      <package id="Microsoft.Azure.Management.ResourceManager" version="1.4.0-preview" targetFramework="net462" />
      <package id="Microsoft.Azure.Management.Sql" version="0.51.0-prerelease" targetFramework="net462" />
      <package id="Microsoft.Bcl" version="1.1.9" targetFramework="net462" />
      <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net462" />
      <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net462" />
      <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="2.18.206251556" targetFramework="net462" />
      <package id="Microsoft.Net.Http" version="2.2.22" targetFramework="net462" />
      <package id="Microsoft.Rest.ClientRuntime" version="2.1.0" targetFramework="net462" />
      <package id="Microsoft.Rest.ClientRuntime.Azure" version="3.1.0" targetFramework="net462" />
      <package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="2.0.1-preview" targetFramework="net462" />
      <package id="Newtonsoft.Json" version="6.0.8" targetFramework="net462" />
    </packages>
    

答案 1 :(得分:-1)

请打开支持案例,以便我们更好地了解问题