2

I am using Azure API's in C# code and used below libraries:

using Microsoft.Rest; using Microsoft.Rest.Azure.Authentication;
using Microsoft.Azure.Management.DataLake.Store;
using Microsoft.Azure.Management.DataLake.StoreUploader;
using Microsoft.Azure.Management.DataLake.Analytics;
using Microsoft.Azure.Management.DataLake.Analytics.Models;
using Microsoft.WindowsAzure.Storage.Blob;

To create connection with Azure:

private static ServiceClientCredentials AuthenticateAzure(string domainName, string nativeClientAppCLIENTID)
{
    // User login via interactive popup
    SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
    // Use the client ID of an existing AAD "Native Client" application.
    var activeDirectoryClientSettings = ActiveDirectoryClientSettings.UsePromptOnly(nativeClientAppCLIENTID, new Uri("urn:ietf:wg:oauth:2.0:oob"));
    return UserTokenProvider.LoginWithPromptAsync(domainName, activeDirectoryClientSettings).Result;
}

When calling LoginWithPromptAsync, I got the popup, which ask my credentials. I don't want this pop-up to appear every time I run the code. Is there any way to come up with this thing beside creating Azure app?

I have an ApplicationId, TenantId, CertificateThumbprint, and SubscriptionId (below). Can I use these fields to authenticate to azure without prompt?

example of credentials

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Ajay
  • 783
  • 3
  • 16
  • 37
  • There are instructions here as to how to create ServicePrinicpal to do this http://blog.davidebbo.com/2015/12/calling-arm-using-plain-rest.html – Darrel Miller Dec 21 '16 at 22:26

1 Answers1

6

We can use the function UserTokenProvider.LoginSilentAsync(nativeClientAppClientid, domainName, userName, password) to get our credentials without pop-up. It works fine for me, the following is my test code. How to registry WebApp please refer to the document.

    static void Main(string[] args)
    {
        var certificate = AuthenticateAzure("your domain name", "Ad App client ID", "username", "password");
    }

    /// <summary>
    ///  Log in to azure active directory in non-interactive mode using organizational
    //   id credentials and the default token cache. Default service settings (authority,
    //   audience) for logging in to azure resource manager are used.
    /// </summary>
    /// <param name="domainName"> The active directory domain or tenant id to authenticate with</param>
    /// <param name="nativeClientAppClientid">  The active directory client id for this application </param>
    /// <param name="userName"> The organizational account user name, given in the form of a user principal name  (e.g. user1@contoso.org).</param>
    /// <param name="password"> The organizational account password.</param>
    /// <returns>A ServiceClientCredentials object that can be used to authenticate http requests  using the given credentials.</returns>
    private static ServiceClientCredentials AuthenticateAzure(string domainName, string nativeClientAppClientid,string userName,string password)
    {
       return UserTokenProvider.LoginSilentAsync(nativeClientAppClientid, domainName, userName, password).Result;
    }

enter image description here

Update:

More details steps about how to registry AD App and assign role to application, please refer to document. After that we can get tenantId, appId, secretKey from the Azure Portal. Then we can use Microsoft.IdentityModel.Clients.ActiveDirectory SDK to get token for api authentication.

Demo code:

var subscriptionId = "Your subscrption";
var appId = "Registried Azure Application Id";
var secretKey = "Secret Key";
var tenantId = "tenant Id";
var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
ClientCredential clientCredential = new ClientCredential(appId, secretKey );
var tokenResponse = context.AcquireTokenAsync("https://management.azure.com/", clientCredential).Result;
var accessToken = tokenResponse.AccessToken;
using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken); 
    client.BaseAddress = new Uri("https://management.azure.com/");
    // Now we can party with our HttpClient!
}

enter image description here

Tom Sun - MSFT
  • 24,161
  • 3
  • 30
  • 47
  • I am using Azure API's for ADLS file access and for some file manipulation and want to integrate with U-SQL project. What would be the "domain name" in that case? Secondly. I don't want to register an app on Azure portal. – Ajay Dec 22 '16 at 06:26
  • Azure also allow to use self-signed management certificate or Azure AD to get authentication. More info about Windows Azure Management Certificates please refer to [document](https://www.simple-talk.com/cloud/security-and-compliance/windows-azure-management-certificates/). domain name: `By default, a basic domain name at .onmicrosoft.com is included with your directory. Later, you can add a domain name that your organization already uses, such as contoso.com.` – Tom Sun - MSFT Dec 22 '16 at 07:10
  • I have application ID, TenantId and other thing. Will this help me to authenticate to azure without prompt. I have edited my question and attached one image.. Can you please help me on this line.. Thanks... – Ajay Dec 22 '16 at 10:27
  • Thanks for your effort... I am using your code as is with AcquireTokenAsync function. As the method is async, control doesn't reach to the next line "var accessToken = tokenResponse.AccessToken;" or does not generate any authentication error.... – Ajay Dec 23 '16 at 13:50
  • Hi Ajay, `var tokenResponse = context.AcquireTokenAsync("https://management.azure.com/", clientCredential).Result` should let us get the tokenResponse. – Tom Sun - MSFT Dec 23 '16 at 13:55
  • Hi Tom, I need `ServiceClientCredentials` object at the end to instantiate `DataLakeStoreFileSystemManagementClient`. I have to access ADLS file system for some file manipulation. For above problem, as we are using async method we have to use `var tokenResponse = context.AcquireTokenAsync("https://management.azure.com/", clientCredential).ConfigureAwait(false)` – Ajay Dec 23 '16 at 19:04
  • Hi Tom.. ur code is working fine with console application and I am able to create DataLakeStoreFileSystemManagementClient object with following code `ServiceClientCredentials creds = new TokenCredentials(tokenResponse.AccessToken); DataLakeStoreFileSystemManagementClient _adlsFileSystemClient = new DataLakeStoreFileSystemManagementClient(creds);` but when I am trying to do any `_adlsFileSystemClient.FileSystem.GetFileStatus(_adlsAccountN‌​ame, Path.Combine(folderPath, fname));` , it return `Microsoft.Azure.Management.DataLake.Store.Models.AdlsErrorException` – Ajay Dec 26 '16 at 07:25
  • hi Ajay, if want to get credential for SDK to init `DataLakeStoreFileSystemManagementClient` object, then we can do it easy with `var creds = ApplicationTokenProvider.LoginSilentAsync(tenantId, applicationId, secretKey).Result;` `var adlsFileSystemClient = new DataLakeStoreFileSystemManagementClient(creds);`. About AdlsErrorExpection, please refer to your another [SO thread](http://stackoverflow.com/questions/41330313/azure-adlserror-webhdfs-error-while-deleting-adls-file) – Tom Sun - MSFT Dec 27 '16 at 07:56
  • I added my role as "Data Lake Analytics Developer" role and everything is working fine... Thanks Tom for your effort. Can you help me on http://stackoverflow.com/questions/41330565/u-sql-error-while-using-reference-assembly?noredirect=1 – Ajay Dec 27 '16 at 13:17