Reputation: 21
I have problem with authorization in azure management API with certificate authorization. When using use Microsoft.Azure.Management.Sql i get error: "AuthenticationFailedInvalidHeader: Authentication failed. The 'Authorization' header is provided in an invalid format." But when I use Microsoft.WindowsAzure.Management.Sql with almost the same code everything works fine, but this is the old version of this library. I need newer version, because old looks like doesn't support elastic pools.
This work just fine
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Management.Sql;
using Microsoft.WindowsAzure.Management.Sql.Models;
namespace Test2
{
class Program
{
private static ServerListResponse servers;
private static string _resourceGroupName = "xxx";
private static string subscriptionId = "xxx";
private static string certThumbprint = "xxx";
static void Main(string[] args)
{
X509Certificate2 cert = GetCertificate(certThumbprint);
SubscriptionCloudCredentials credentials = new CertificateCloudCredentials(subscriptionId, cert);
SqlManagementClient client = new SqlManagementClient(credentials);
servers = client.Servers.List();
Console.ReadKey();
}
}
}
This generate error
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Microsoft.Azure;
using Microsoft.Azure.Management.Sql;
using Microsoft.Azure.Management.Sql.Models;
namespace Test2
{
class Program
{
private static ServerListResponse servers;
private static string _resourceGroupName = "xxx";
private static string subscriptionId = "xxx";
private static string certThumbprint = "xxx";
static void Main(string[] args)
{
X509Certificate2 cert = GetCertificate(certThumbprint);
SubscriptionCloudCredentials credentials = new CertificateCloudCredentials(subscriptionId, cert);
SqlManagementClient client = new SqlManagementClient(credentials);
Task.Run(async () =>
{
servers = await client.Servers.ListAsync(_resourceGroupName);
}).Wait();
Console.ReadKey();
}
}
}
Upvotes: 2
Views: 1150
Reputation: 2267
For Microsoft.Azure, they change the authorization strategy. X509Certificates is no longer supported like that. However, you can use ADAL with an interactive login or a Service Principal.
Here is a sample code:
Interactive login:
using System;
using System.Security;
using Microsoft.Azure.Management.Sql;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Azure;
namespace GetSqlARM
{
class Program
{
static void Main(string[] args)
{
var token = GetTokenCloudCredentials();
SqlManagementClient client = new SqlManagementClient(token);
var server = client.Servers.Get("<Your Resource Group>", "<Your Sql Server>");
System.Console.WriteLine(server.ToString());
System.Console.WriteLine("Press ENTER to continue");
System.Console.ReadLine();
}
public static TokenCloudCredentials GetTokenCloudCredentials()
{
String tenantID = "<Your Tenant ID>";
String loginEndpoint = "https://login.windows.net/";
Uri redirectURI = new Uri("urn:ietf:wg:oauth:2.0:oob");
String clientID = "1950a258-227b-4e31-a9cf-717495945fc2";
String subscriptionID = "<Your Subscription ID>";
String resource = "https://management.core.windows.net/";
String authString = loginEndpoint + tenantID;
AuthenticationContext authenticationContext = new AuthenticationContext(authString, false);
var promptBehaviour = PromptBehavior.Auto;
var userIdentifierType = UserIdentifierType.RequiredDisplayableId;
var userIdentifier = new UserIdentifier("<Your Azure Account>", userIdentifierType);
var authenticationResult = authenticationContext.AcquireToken(resource, clientID, redirectURI, promptBehaviour, userIdentifier);
return new TokenCloudCredentials(subscriptionID, authenticationResult.AccessToken);
}
}
}
Service Principal:
Replace the GetTokenCloudCredentials method in the above program by the following.
public static TokenCloudCredentials GetTokenCloudCredentials()
{
String tenantID = "<Your Tenant ID>";
String loginEndpoint = "https://login.windows.net/";
String subscriptionID = "<Your Subscription ID>";
String authString = loginEndpoint + tenantID;
String clientID = "<Your Client ID>";
String key = "<Your Client Key>";
var clientCred = new ClientCredential(clientID, key);
String resource = "https://management.core.windows.net/";
AuthenticationContext authenticationContext = new AuthenticationContext(authString, false);
var authenticationResult = authenticationContext.AcquireToken(resource, clientCred);
return new TokenCloudCredentials(subscriptionID, authenticationResult.AccessToken);
}
In order to use the Service Principal Code, you need to follow this article to create a Service Principal.
For those package, I am using the following version:
Upvotes: 1
Reputation: 3361
The new api uses resource manager, in which the typical scenario is to use a client id /secret or username/password for authentication.
That said, if you want to stick with certificates that's certainly possible, but it does require a bit of work to set up. ARM basically authenticates "thru" an application, and you can configure pki on that application. I wrote about the configuration (using PowerShell but should be transferable) a while back:
Upvotes: 0