Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
namespace Postcode.Performance.Plugins
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.WebTesting;
using Newtonsoft.Json.Linq;
[Description("Generates ZuMo token for Azure Api & Mobile Apps in client flow scenario.")]
[DisplayName("Generate ZuMo Token (Client Flow)")]
public class ZumoTokenClientFlowPlugin : WebTestPlugin
{
private ReaderWriterLockSlim _cacheLock = new ReaderWriterLockSlim();
private static Dictionary<string, string> zumoTokenCache = new Dictionary<string, string>();
[DisplayName("Target Context Parameter Name")]
[Description("Name of the context parameter that will receive the retrieved ZuMo token.")]
public string ContextParamTarget { get; set; }
[DisplayName("Azure AD Authority Base URL")]
[Description("Example: https://login.microsoftonline.com")]
public string AzureADAuthorityBaseUrl { get; set; }
[DisplayName("App Service Gateway URL")]
[Description("Example: https://xxxxxxx.azurewebsites.net/")]
public string AppServiceGatewayURL { get; set; }
[DisplayName("Azure AD Tenant")]
[Description("You can use a domain name or tenant Id Example: abc.com OR 1de4b508-d463-4547-7cee-dcaac3501123")]
public string AzureADTenant { get; set; }
[DisplayName("Azure AD App Client Id")]
[Description("Example: fde5f9bf-df94-42af-ba44-391453a0b333")]
public string ClientId { get; set; }
[DisplayName("Azure AD App Key/Secret")]
[Description("Example: +9PBng0ZO1xU2dfshR23dweQPx1Cs6+3joSMAh1/sE=")]
public string SecretKey { get; set; }
public override void PreWebTest(object sender, PreWebTestEventArgs e)
{
if (!zumoTokenCache.ContainsKey(this.AppServiceGatewayURL))
{
var tokenTask = this.GetZumoAccessToken();
tokenTask.Wait();
try
{
this._cacheLock.EnterWriteLock();
if (!zumoTokenCache.ContainsKey(this.AppServiceGatewayURL))
{
zumoTokenCache.Add(this.AppServiceGatewayURL, tokenTask.Result);
}
}
finally
{
this._cacheLock.ExitWriteLock();
}
}
e.WebTest.Context.Add(this.ContextParamTarget, zumoTokenCache[this.AppServiceGatewayURL]);
base.PreWebTest(sender, e);
}
public async Task<string> GetZumoAccessToken()
{
var aadAuthorityUrl = this.AzureADAuthorityBaseUrl;
var gatewayUrl = this.AppServiceGatewayURL;
using (var accessTokenClient = new HttpClient())
{
var accessTokenContent = new FormUrlEncodedContent(
new[] {
new KeyValuePair<string, string>(
"resource",
string.Format(
CultureInfo.InvariantCulture,
"{0}{1}", this.AppServiceGatewayURL, "/login/aad")),
new KeyValuePair<string, string>("client_id", this.ClientId),
new KeyValuePair<string, string>("client_secret", this.SecretKey),
new KeyValuePair<string, string>("grant_type", "client_credentials")
});
accessTokenClient.BaseAddress = new Uri(aadAuthorityUrl);
var accessTokenReplyContent = await accessTokenClient.PostAsync(
string.Format(CultureInfo.InvariantCulture,
"/{0}/oauth2/token", this.AzureADTenant), accessTokenContent);
if (accessTokenReplyContent.IsSuccessStatusCode)
{
var accessTokenReplyJson = JToken.Parse(await accessTokenReplyContent.Content.ReadAsStringAsync());
using (var zumoTokenClient = new HttpClient())
{
var jsonObject = new JObject();
jsonObject.Add("access_token", accessTokenReplyJson["access_token"]);
var zumoTokenContent = new StringContent(jsonObject.ToString());
zumoTokenClient.BaseAddress = new Uri(gatewayUrl);
var zumoTokenReplyContent = await zumoTokenClient.PostAsync("/login/aad", zumoTokenContent);
if (zumoTokenReplyContent.IsSuccessStatusCode)
{
var zumoTokenReplyJson = JToken.Parse(await zumoTokenReplyContent.Content.ReadAsStringAsync());
return zumoTokenReplyJson["authenticationToken"].ToString();
}
}
}
}
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment