18

To authenticate with Azure in azure sdk fluent nuget, there is a method that uses client id and secret as below

var azureCredentials = new AzureCredentials(new 
ServicePrincipalLoginInformation
        {
            ClientId = "ClientId",
            ClientSecret = "ClientSecret"
        }, "tenantId", AzureEnvironment.AzureGlobalCloud);

Is there any interface where authentication token (JWT) can be used instead of using client id and secret while creating IAzure in the below code?

_azure = Azure
            .Configure()
            .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
            .Authenticate(azureCredentials)
            .WithSubscription(_subscriptionId); 

Note: I have a separate authenticater module that keeps client id and secret with itself and uses them to get authentication token which will be used by other components/sdks.

Saravanan
  • 920
  • 9
  • 22

3 Answers3

23

The answer is actually yes, you can use the authentication token (JWT). It's just not that obvious.

var context = new AuthenticationContext("https://login.microsoftonline.com/" + tenantId, false);
var result = context.AcquireToken("https://management.core.windows.net/", clientId, new Uri("http://localhost"), PromptBehavior.Always);
var token = result.AccessToken;
var client = RestClient
    .Configure()
    .WithEnvironment(AzureEnvironment.AzureGlobalCloud)
    .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
    .WithCredentials(new TokenCredentials(token))
    .Build();
var azure = Azure
    .Authenticate(client, tenantId)
    .WithSubscription(subscriptionId);

Sigh...they've changed the WithCredentials to use an AzureCredentials instead of a ServiceClientCredentials. Here's an updated version:-

var context = new AuthenticationContext("https://login.microsoftonline.com/" + tenantId, false);
var result = context.AcquireToken("https://management.core.windows.net/", clientId, new Uri("http://localhost"), PromptBehavior.Always);
var token = result.AccessToken;
var tokenCredentials = new TokenCredentials(token);
var azureCredentials = new AzureCredentials(
    tokenCredentials,
    tokenCredentials,
    tenantId,
    AzureEnvironment.AzureGlobalCloud);
var client = RestClient
    .Configure()
    .WithEnvironment(AzureEnvironment.AzureGlobalCloud)
    .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
    .WithCredentials(azureCredentials)
    .Build();
var azure = Azure
    .Authenticate(client, tenantId)
    .WithSubscription(subscriptionId);
Aranha
  • 2,903
  • 3
  • 14
  • 29
jonny
  • 239
  • 1
  • 5
9

Starting from Azure Management Fluent SDK v1.10 you can use any credentials provider that is derived from ServiceClientCredentials. In other words you should be able to pass already acquired Bearer token string to AzureCredentials constructor like this

var customTokenProvider = new AzureCredentials(
                        new TokenCredentials(armAuthToken),
                        new TokenCredentials(graphAuthToken),
                        tenantId,
                        AzureEnvironment.AzureGlobalCloud);

var client = RestClient
                    .Configure()
                    .WithEnvironment(AzureEnvironment.AzureGlobalCloud)
                    .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
                    .WithCredentials(customTokenProvider)
                    .Build();

var authenticatedClient = Azure.Authenticate(client, tenantId);
hovsepm
  • 146
  • 1
  • 3
  • 4
    Can you describe where you're getting "armAuthToken" and "graphAuthToken"? The other examples seem to imply you can use the Bearer token for both of those inputs but I'm not having luck doing this. I'm not sure how the underlying HttpClient for the library would know these are Bearer tokens given this example. – Cory Gehr Sep 12 '19 at 17:02
0

Is there any interface where authentication token (JWT) can be used instead of using client id and secret while creating IAzure in the below code?

In short no. Base on my experence, if we want to access the corresponding Azure resources then we need to get the authentication token (JWT) from the corresponding resources. Azure has lots of resources such as AzureSQL, KeyVault, ResourceManagement etc.

On my option, it is not make senses that use the authentication token (JWT) that can access all of the Azure Resources.

Currently, we could get AzureCredentials from file, ServicePrincipalLoginInformation, UserLoginInformation

If we want to operate a certain resource, then we could use authentication token (JWT) to do, take KeyVault as example.

    public static async Task<string> GetAccessToken(string azureTenantId,string azureAppId,string azureSecretKey)
    {

        var context = new AuthenticationContext("https://login.windows.net/" + azureTenantId);
        ClientCredential clientCredential = new ClientCredential(azureAppId, azureSecretKey);
        var tokenResponse =await context.AcquireTokenAsync("https://vault.azure.net", clientCredential); //KeyVault resource : https://vault.azure.net
        var accessToken = tokenResponse.AccessToken;
        return accessToken;
    }

    var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken));
Tom Sun - MSFT
  • 24,161
  • 3
  • 30
  • 47
  • We are using service principal and certificate (without using secret) to get the access token which is used in insightsclient, telemetry and etc... With this new fluent sdk, I would like to use that token without resorting to client id and secret. Is there any future plan to expose token based interface? – Saravanan May 24 '17 at 20:01
  • `Is there any future plan to expose token based interface?` On my option, it is not make senses that use the authentication token (JWT) that can access all of the Azure Resources. If you have any idea, you also can give you [feedback](https://feedback.azure.com/forums/34192--general-feedback) to azure team. – Tom Sun - MSFT May 25 '17 at 07:01