Skip to content

Instantly share code, notes, and snippets.

@loic-sharma
Last active August 3, 2018 04:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loic-sharma/dca161747f13a62a6bcf8b1d04259445 to your computer and use it in GitHub Desktop.
Save loic-sharma/dca161747f13a62a6bcf8b1d04259445 to your computer and use it in GitHub Desktop.
Authenticating to a private BaGet feed using Azure Active Directory's Device Flow Authentication
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
namespace DeviceFlow
{
class Program
{
public const string Tenant = "tenantname.onmicrosoft.com";
public const string AppId = "33333333-3333-3333-3333-333333333333";
public const string Resource = "22222222-2222-2222-2222-222222222222";
public static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
}
public static async Task MainAsync(string[] args)
{
// Authenticate the app
var context = new AuthenticationContext($"https://login.microsoftonline.com/{Tenant}");
var token = await GetToken(context);
if (token == null)
{
Console.WriteLine("Failed to authenticate.");
return;
}
// Based off https://github.com/Azure-Samples/active-directory-dotnet-native-headless
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = ConvertTokenToBasicAuth(token);
using (var response = await httpClient.GetAsync("http://localhost:50557/v3/registration/Newtonsoft.Json/11.0.2.json"))
{
Console.WriteLine(await response.Content.ReadAsStringAsync());
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($"Response indicates unsuccessful request. {response.StatusCode}: {response.ReasonPhrase}");
return;
}
Console.WriteLine("Success!");
}
}
}
static AuthenticationHeaderValue ConvertTokenToBasicAuth(AuthenticationResult token)
{
var bytes = Encoding.ASCII.GetBytes($"BaGet:{token.AccessToken}");
var value = Convert.ToBase64String(bytes);
return new AuthenticationHeaderValue("Basic", value);
}
// Based off https://github.com/Azure-Samples/active-directory-dotnet-deviceprofile/blob/master/DirSearcherClient/Program.cs#L206-L210
static async Task<AuthenticationResult> GetToken(AuthenticationContext context)
{
try
{
return await context.AcquireTokenSilentAsync(Resource, AppId);
}
catch (AdalSilentTokenAcquisitionException)
{
return await GetTokenViaCode(context);
}
catch (AdalException e)
{
Console.WriteLine($"Failed to get token due to exception: {e}");
throw;
}
}
static async Task<AuthenticationResult> GetTokenViaCode(AuthenticationContext context)
{
try
{
var codeResult = await context.AcquireDeviceCodeAsync(Resource, AppId);
Console.WriteLine($"Message: {codeResult.Message}");
return await context.AcquireTokenByDeviceCodeAsync(codeResult);
}
catch (Exception e)
{
Console.WriteLine($"Failed to acquire token using device flow: {e}");
throw;
}
}
}
}
@loic-sharma
Copy link
Author

resource is the service's AAD application ID.
clientId is the app's AAD application ID.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment