I am trying to create an Azure Database programmatically using C# via the HTTP API.
I found this resource (in which he uses App Secret, rather than certificate), but can't get it to work due to a 403: Forbidden error.
If I use the token created in the 'try it' section of the azure docs, the code works fine, so it must be that the token generated doesn't have the permissions I need.
The secret I am trying to use was generated in Portal > Active Directory > App Registrations > {myapp} > Certificates and Secrets.
In API permissions I've added just about everything - though please suggest any I might have missed!
I opened the firewall to my IP and have spent hours looking for the answer, but can't seem to figure it out.
What am I missing please?
Although I believe it's permissions somewhere in Azure, here's my code:
/// <summary>
/// Create a new database
/// </summary>
/// <param name="subscriptionId">See Portal > Subscriptions (pick the right subscription!)</param>
/// <param name="resourceGroupName">The resource group the server was created in</param>
/// <param name="locationName">e.g. UK (South)</param>
/// <param name="sqlServeName">The name of the SQL Server VM created when the first database was created</param>
/// <param name="tenantId">See GetAccessToken</param>
/// <param name="clientId">See GetAccessToken</param>
/// <param name="clientSecret">See GetAccessToken</param>
/// <param name="databaseName">The name of the database to be created</param>
/// <returns></returns>
private async Task CreateDatabaseAsync(string subscriptionId, string resourceGroupName, string locationName, string sqlServeName, string tenantId, string clientId, string clientSecret, string databaseName)
{
var token = await GetAccessTokenAsync(tenantId, clientId, clientSecret);
var url = "https://management.azure.com/subscriptions/" + subscriptionId + "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Sql/servers/" + sqlServeName + "/databases/" + databaseName + "?api-version=2017-10-01-preview";
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Remove("Authorization");
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
string requestBody = "{location: \"" + locationName + "\"}";
HttpResponseMessage response = await httpClient.PutAsync(url, new StringContent(requestBody, Encoding.UTF8, "application/json"));
var statusCode = response.StatusCode.ToString();
}
/// <summary>
/// Gets and access token with which to call the Azure API
/// </summary>
/// <param name="tenantId">See Portal > Active Directory > Properties > Overview for this value</param>
/// <param name="clientId">See Portal > Active Directory > App Registrations > This App > Overview for this value</param>
/// <param name="clientSecret">See Portal > Active Directory > App Registrations > This App > Certificates & Secrets > Generate Secret </param>
/// <returns></returns>
private async Task<string> GetAccessTokenAsync(string tenantId, string clientId, string clientSecret)
{
Console.WriteLine("Begin GetAccessToken");
string authContextURL = "https://login.windows.net/" + tenantId;
var authenticationContext = new AuthenticationContext(authContextURL);
var credential = new ClientCredential(clientId, clientSecret);
var result = await authenticationContext
.AcquireTokenAsync("https://management.azure.com/", credential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
return token;
}
