Skip to content

Instantly share code, notes, and snippets.

@jpda
Last active July 24, 2018 22:06
Show Gist options
  • Select an option

  • Save jpda/a4b79fdbba854682ab2cdf2c59c25d2d to your computer and use it in GitHub Desktop.

Select an option

Save jpda/a4b79fdbba854682ab2cdf2c59c25d2d to your computer and use it in GitHub Desktop.
Simple graph query by attribute
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="3.19.8" />
</ItemGroup>
</Project>
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using System.Linq;
private static HttpClient _client;
public static async Task<IActionResult> Run(HttpRequest req, TraceWriter log)
{
log.Info($"Received validation request");
var config = new ConfigurationBuilder().AddEnvironmentVariables().Build();
var tenant = config["AzureAd::Tenant"];
var client = config["AzureAd::ClientId"];
var secret = config["AzureAd::Secret"];
var resource = config["AzureAd::Resource"];
var extensionAttributeName = config["AzureAd::ExtensionAttributeName"];
// read and parse incoming claim values
// todo: be more defensive
var requestBody = string.Empty;
using (var reader = new StreamReader(req.Body, System.Text.Encoding.UTF8))
{
requestBody = await reader.ReadToEndAsync();
}
dynamic incomingClaimData = JsonConvert.DeserializeObject(requestBody);
var appUserId = ((string)incomingClaimData.AppUserId).ToLower();
var query = $"$filter={extensionAttributeName} eq '{appUserId}'";
// get a token for talking to the graph
var ctx = new AuthenticationContext($"https://login.microsoftonline.com/{tenant}");
var token = await ctx.AcquireTokenAsync(resource, new ClientCredential(client, secret));
if(_client == null)
{
_client = new HttpClient();
}
_client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token.AccessToken);
var response = await _client.GetAsync($"https://graph.windows.net/{tenant}/users?api-version=1.6&{query}");
var data = await response.Content.ReadAsStringAsync();
var thing = JObject.Parse(data);
var people = ((JArray)thing["value"]);
//fail safe - if the function bombs or the json parsing fails, always fail to true, which implies a user with that field and value exists
var usersExistWithAppUserId = true;
if(people.Count() == 0)
{
usersExistWithAppUserId = false;
}
// return a simplified set of values, since this is what our provider will expose into claims
return query != null
? (ActionResult)new OkObjectResult(new { usersExistWithAppUserId })
: new BadRequestObjectResult("Please pass an odata $filter or attribute/value query");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment