get role assignments and userinfo using ARM and Graph API on Functions
using System; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.Azure.WebJobs; | |
using Microsoft.Azure.WebJobs.Extensions.Http; | |
using Microsoft.AspNetCore.Http; | |
using Microsoft.Extensions.Logging; | |
using Microsoft.Extensions.Configuration; | |
using Microsoft.IdentityModel.Clients.ActiveDirectory; | |
using System.Net.Http; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace FunctionApp7 | |
{ | |
public static class Function1 | |
{ | |
static Function1() | |
{ | |
var builder = new ConfigurationBuilder() | |
.AddJsonFile("local.settings.json", true, false) | |
.AddJsonFile("secret.settings.json", true, false) | |
.AddEnvironmentVariables(); | |
Configuration = builder.Build(); | |
} | |
private static async Task<AuthenticationResult> GetS2SAccessToken(string authority, string resource, string clientId, string clientSecret) | |
{ | |
var clientCredential = new ClientCredential(clientId, clientSecret); | |
AuthenticationContext context = new AuthenticationContext(authority, false); | |
AuthenticationResult authenticationResult = await context.AcquireTokenAsync( | |
resource, | |
clientCredential); | |
return authenticationResult; | |
} | |
private static IConfigurationRoot Configuration { get; } | |
private static HttpClient Client = new HttpClient(); | |
[FunctionName("Function1")] | |
public static async Task<IActionResult> Run( | |
[HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, | |
ILogger log) | |
{ | |
try | |
{ | |
// トークンの期限は考慮してないので注意 | |
var token = await GetS2SAccessToken( | |
string.Format("https://login.microsoftonline.com/{0}/", Configuration["Tenant"]), | |
"https://management.azure.com/", | |
Configuration["AppId"], | |
Configuration["AppSecret"] | |
); | |
var tokengraph = await GetS2SAccessToken( | |
string.Format("https://login.microsoftonline.com/{0}/", Configuration["Tenant"]), | |
"https://graph.microsoft.com/", | |
Configuration["AppId"], | |
Configuration["AppSecret"] | |
); | |
var subscriptionId = req.Query["subscriptionid"]; | |
// ロール割り当ての取得 | |
var roleassignments = Utf8Json.JsonSerializer.Deserialize<dynamic>(await GetRoleAssignment(subscriptionId, token.CreateAuthorizationHeader())); | |
var results = await Task.WhenAll( | |
(roleassignments["value"] as List<dynamic>)?.AsParallel() | |
.Select(async val => | |
{ | |
var assigninfo = new { id = val["id"], principalId = val["properties"]["principalId"], roleid = val["properties"]["roleDefinitionId"] }; | |
// 割り当てられているユーザーの情報を取得 | |
string ui = await GetUserInformation(assigninfo.principalId, tokengraph.CreateAuthorizationHeader()); | |
if (string.IsNullOrWhiteSpace(ui)) return null; // 取れない場合ユーザーじゃない可能性もあり(App/Group他 ※手抜き) | |
var user = Utf8Json.JsonSerializer.Deserialize<dynamic>(ui); | |
var roledef = Utf8Json.JsonSerializer.Deserialize<dynamic>(await GetRoleDefine(assigninfo.roleid, token.CreateAuthorizationHeader())); | |
return new | |
{ | |
id = assigninfo.principalId, | |
name = user["displayName"], | |
upn = user["userPrincipalName"], | |
mail = user["mail"], | |
roleid = assigninfo.roleid, | |
rolename = roledef["properties"]["roleName"] | |
}; | |
} | |
) | |
); | |
return new JsonResult(results.Where(x => x != null)); | |
} | |
catch (Exception ex) | |
{ | |
log.LogError(ex.Message); | |
throw; | |
} | |
} | |
static async Task<string> InvokeApi(string requesturi, string authheader) | |
{ | |
var request = new HttpRequestMessage() | |
{ | |
Method = HttpMethod.Get, | |
RequestUri = new Uri(requesturi), | |
}; | |
request.Headers.Add("Authorization", authheader); | |
var res = await Client.SendAsync(request); | |
if (res.StatusCode != System.Net.HttpStatusCode.OK) return null; | |
return await res.Content.ReadAsStringAsync(); | |
} | |
static async Task<string> GetRoleAssignment(string subscriptionId, string authheader) | |
{ | |
return await InvokeApi( | |
$"https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleAssignments?api-version=2015-07-01", | |
authheader | |
); | |
} | |
static async Task<string> GetRoleDefine(string roleId, string authheader) | |
{ | |
return await InvokeApi( | |
$"https://management.azure.com/{roleId}?api-version=2015-07-01", | |
authheader | |
); | |
} | |
static async Task<string> GetUserInformation(string userid, string authheader) | |
{ | |
return await InvokeApi( | |
$"https://graph.microsoft.com/v1.0/users/{userid}", | |
authheader | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment