From b454b87940df1f0e3b6c040aefdf85e0f5c38eeb Mon Sep 17 00:00:00 2001 From: Grace Tsao Date: Mon, 19 Jul 2021 20:28:02 -0700 Subject: [PATCH 1/8] Intial outline --- .../GraphExplorerAppModeController.cs | 133 +++++++++++++++++- GraphWebApi/GraphWebApi.csproj | 2 + GraphWebApi/Startup.cs | 1 + 3 files changed, 131 insertions(+), 5 deletions(-) diff --git a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs index 1ef5456a2..bac0668b4 100644 --- a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs +++ b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs @@ -9,6 +9,11 @@ using Microsoft.Identity.Web; using System.Net.Http; using System.Net.Http.Headers; +using Microsoft.Graph; +using System.Net; +using Microsoft.Identity.Client; +using System.Threading; +using Microsoft.Extensions.Primitives; namespace GraphWebApi.Controllers { @@ -16,13 +21,16 @@ namespace GraphWebApi.Controllers public class GraphExplorerAppModeController : ControllerBase { private readonly ITokenAcquisition tokenAcquisition; - public GraphExplorerAppModeController(ITokenAcquisition tokenAcquisition) + private readonly GraphServiceClient _graphServiceClient; + public GraphExplorerAppModeController(ITokenAcquisition tokenAcquisition, GraphServiceClient graphServiceClient) { this.tokenAcquisition = tokenAcquisition; + this._graphServiceClient = graphServiceClient; } [Route("api/[controller]/{*all}")] [Route("graphproxy/{*all}")] [HttpGet] + [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] public async Task GetAsync(string all) { return await ProcessRequestAsync("GET", all, null).ConfigureAwait(false); @@ -36,12 +44,14 @@ public async Task GetTokenAsync(string all) { // Acquire the access token. string scopes = "https://graph.microsoft.com/.default"; + return await tokenAcquisition.GetAccessTokenForAppAsync(scopes); - } + } [Route("api/[controller]/{*all}")] [Route("graphproxy/{*all}")] [HttpPost] + [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] public async Task PostAsync(string all, [FromBody] object body) { return await ProcessRequestAsync("POST", all, body).ConfigureAwait(false); @@ -52,20 +62,133 @@ public async Task PostAsync(string all, [FromBody] object body) [HttpDelete] public async Task DeleteAsync(string all) { - return await ProcessRequestAsync("DELETE", all, null).ConfigureAwait(false); + try + { + string accessToken = GetTokenAsync("").Result.ToString(); + HttpClient httpClient = new HttpClient(); + httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + var response = await httpClient.DeleteAsync("https://graph.microsoft.com/v1.0/teams/8248c7dd-f773-40a5-b090-19386856ced3/channels/19:cfc8004ddb25441b8be2b7c5da02967a@thread.tacv2"); + response.EnsureSuccessStatusCode(); + Console.WriteLine("http status code is ok"); + Console.WriteLine(response.ReasonPhrase); + Console.WriteLine(response.Content); + return Ok(response.ReasonPhrase); + } + catch (Exception exception) + { + Console.WriteLine("IT WENT INTO EXCEPTTTTTTTTT"); + return new JsonResult(exception) { StatusCode = 404 }; + } + return null; } [Route("api/[controller]/{*all}")] [Route("graphproxy/{*all}")] [HttpPut] - public async Task PutAsync(string all, [FromBody] object body) + [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] + public async Task PutAsync(string all) { - return await ProcessRequestAsync("PUT", all, body).ConfigureAwait(false); + GraphServiceClient _graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider( + async requestMessage => + { + // Passing tenant ID to the sample auth provider to use as a cache key + string accessToken = GetTokenAsync("").Result.ToString(); + // Append the access token to the request + requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + })); + + var qs = HttpContext.Request.QueryString; + Console.WriteLine(HttpContext); + + var url = $"{GetBaseUrlWithoutVersion(_graphServiceClient)}/{all}{qs.ToUriComponent()}"; + + Console.WriteLine("IS IT IN HERE"); + + var request = new BaseRequest(url, _graphServiceClient, null) + { + Method = "DELETE", + ContentType = HttpContext.Request.ContentType, + }; + + var contentType = "application/json"; + object content = null; + try + { + using (var response = await request.SendRequestAsync(content?.ToString(), CancellationToken.None , HttpCompletionOption.ResponseContentRead).ConfigureAwait(false)) + { + response.Content.Headers.TryGetValues("content-type", out var contentTypes); + + contentType = contentTypes?.FirstOrDefault() ?? contentType; + + var byteArrayContent = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false); + Console.WriteLine(byteArrayContent); + return new HttpResponseMessageResult(ReturnHttpResponseMessage(HttpStatusCode.OK, contentType, new ByteArrayContent(byteArrayContent))); + } + } + catch (ServiceException ex) + { + return new HttpResponseMessageResult(ReturnHttpResponseMessage(ex.StatusCode, contentType, new StringContent(ex.Error.ToString()))); + } + } + + private static HttpResponseMessage ReturnHttpResponseMessage(HttpStatusCode httpStatusCode, string contentType, HttpContent httpContent) + { + var httpResponseMessage = new HttpResponseMessage(httpStatusCode) + { + Content = httpContent + }; + + try + { + httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType); + } + catch + { + httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + } + + return httpResponseMessage; + } + + private string GetBaseUrlWithoutVersion(GraphServiceClient graphClient) + { + var baseUrl = graphClient.BaseUrl; + var index = baseUrl.LastIndexOf('/'); + return baseUrl.Substring(0, index); + } + + public class HttpResponseMessageResult : IActionResult + { + private readonly HttpResponseMessage _responseMessage; + + public HttpResponseMessageResult(HttpResponseMessage responseMessage) + { + _responseMessage = responseMessage; // could add throw if null + } + + public async Task ExecuteResultAsync(ActionContext context) + { + context.HttpContext.Response.StatusCode = (int)_responseMessage.StatusCode; + + foreach (var header in _responseMessage.Headers) + { + context.HttpContext.Response.Headers.TryAdd(header.Key, new StringValues(header.Value.ToArray())); + } + + context.HttpContext.Response.ContentType = _responseMessage.Content.Headers.ContentType.ToString(); + + using (var stream = await _responseMessage.Content.ReadAsStreamAsync()) + { + await stream.CopyToAsync(context.HttpContext.Response.Body); + await context.HttpContext.Response.Body.FlushAsync(); + } + } } [Route("api/[controller]/{*all}")] [Route("graphproxy/{*all}")] [HttpPatch] + [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] public async Task PatchAsync(string all, [FromBody] object body) { return await ProcessRequestAsync("PATCH", all, body).ConfigureAwait(false); diff --git a/GraphWebApi/GraphWebApi.csproj b/GraphWebApi/GraphWebApi.csproj index 99e0191a5..20b3fd145 100644 --- a/GraphWebApi/GraphWebApi.csproj +++ b/GraphWebApi/GraphWebApi.csproj @@ -49,10 +49,12 @@ + + diff --git a/GraphWebApi/Startup.cs b/GraphWebApi/Startup.cs index e121b50d8..f63d2c7fe 100644 --- a/GraphWebApi/Startup.cs +++ b/GraphWebApi/Startup.cs @@ -51,6 +51,7 @@ public void ConfigureServices(IServiceCollection services) services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(Configuration, "AzureAd") .EnableTokenAcquisitionToCallDownstreamApi() + .AddMicrosoftGraph(Configuration.GetSection("GraphV1")) .AddInMemoryTokenCaches(); services.AddDistributedMemoryCache(); services.AddAuthentication(option => From cff07fbecab6830f20653bae305471beca4975f5 Mon Sep 17 00:00:00 2001 From: Grace Tsao Date: Tue, 20 Jul 2021 00:27:08 -0700 Subject: [PATCH 2/8] Works and moved into methods --- .../GraphExplorerAppModeController.cs | 144 +++++++++--------- 1 file changed, 68 insertions(+), 76 deletions(-) diff --git a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs index bac0668b4..cebaff3ed 100644 --- a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs +++ b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs @@ -33,7 +33,7 @@ public GraphExplorerAppModeController(ITokenAcquisition tokenAcquisition, GraphS [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] public async Task GetAsync(string all) { - return await ProcessRequestAsync("GET", all, null).ConfigureAwait(false); + return await this.ProcessRequestAsync("GET", all, null).ConfigureAwait(false); } [Route("api/[controller]/{*all}")] @@ -54,6 +54,7 @@ public async Task GetTokenAsync(string all) [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] public async Task PostAsync(string all, [FromBody] object body) { + Console.WriteLine(body); return await ProcessRequestAsync("POST", all, body).ConfigureAwait(false); } @@ -62,40 +63,72 @@ public async Task PostAsync(string all, [FromBody] object body) [HttpDelete] public async Task DeleteAsync(string all) { - try + return await ProcessRequestAsync("DELETE", all, null).ConfigureAwait(false); + } + + [Route("api/[controller]/{*all}")] + [Route("graphproxy/{*all}")] + [HttpPut] + [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] + public async Task PutAsync(string all, [FromBody] object body) + { + return await ProcessRequestAsync("PUT", all, body).ConfigureAwait(false); + } + + private string GetBaseUrlWithoutVersion(GraphServiceClient graphClient) + { + var baseUrl = graphClient.BaseUrl; + var index = baseUrl.LastIndexOf('/'); + return baseUrl.Substring(0, index); + } + + public class HttpResponseMessageResult : IActionResult + { + private readonly HttpResponseMessage _responseMessage; + + public HttpResponseMessageResult(HttpResponseMessage responseMessage) { - string accessToken = GetTokenAsync("").Result.ToString(); - HttpClient httpClient = new HttpClient(); - httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - var response = await httpClient.DeleteAsync("https://graph.microsoft.com/v1.0/teams/8248c7dd-f773-40a5-b090-19386856ced3/channels/19:cfc8004ddb25441b8be2b7c5da02967a@thread.tacv2"); - response.EnsureSuccessStatusCode(); - Console.WriteLine("http status code is ok"); - Console.WriteLine(response.ReasonPhrase); - Console.WriteLine(response.Content); - return Ok(response.ReasonPhrase); + _responseMessage = responseMessage; // could add throw if null } - catch (Exception exception) + + public async Task ExecuteResultAsync(ActionContext context) { - Console.WriteLine("IT WENT INTO EXCEPTTTTTTTTT"); - return new JsonResult(exception) { StatusCode = 404 }; + context.HttpContext.Response.StatusCode = (int)_responseMessage.StatusCode; + + foreach (var header in _responseMessage.Headers) + { + context.HttpContext.Response.Headers.TryAdd(header.Key, new StringValues(header.Value.ToArray())); + } + + context.HttpContext.Response.ContentType = _responseMessage.Content.Headers.ContentType.ToString(); + + using (var stream = await _responseMessage.Content.ReadAsStreamAsync()) + { + await stream.CopyToAsync(context.HttpContext.Response.Body); + await context.HttpContext.Response.Body.FlushAsync(); + } } - return null; } [Route("api/[controller]/{*all}")] [Route("graphproxy/{*all}")] - [HttpPut] + [HttpPatch] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task PutAsync(string all) + public async Task PatchAsync(string all, [FromBody] object body) + { + return await ProcessRequestAsync("PATCH", all, body).ConfigureAwait(false); + } + + private async Task ProcessRequestAsync(string method, string all, object content) { GraphServiceClient _graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider( - async requestMessage => - { - // Passing tenant ID to the sample auth provider to use as a cache key - string accessToken = GetTokenAsync("").Result.ToString(); - // Append the access token to the request - requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - })); + async requestMessage => + { + // Passing tenant ID to the sample auth provider to use as a cache key + string accessToken = GetTokenAsync("").Result.ToString(); + // Append the access token to the request + requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + })); var qs = HttpContext.Request.QueryString; Console.WriteLine(HttpContext); @@ -106,15 +139,23 @@ public async Task PutAsync(string all) var request = new BaseRequest(url, _graphServiceClient, null) { - Method = "DELETE", + Method = method, ContentType = HttpContext.Request.ContentType, }; + var neededHeaders = Request.Headers.Where(h => h.Key.ToLower() == "if-match" || h.Key.ToLower() == "consistencylevel").ToList(); + if (neededHeaders.Count() > 0) + { + foreach (var header in neededHeaders) + { + request.Headers.Add(new HeaderOption(header.Key, string.Join(",", header.Value))); + } + } + var contentType = "application/json"; - object content = null; try { - using (var response = await request.SendRequestAsync(content?.ToString(), CancellationToken.None , HttpCompletionOption.ResponseContentRead).ConfigureAwait(false)) + using (var response = await request.SendRequestAsync(content?.ToString(), CancellationToken.None, HttpCompletionOption.ResponseContentRead).ConfigureAwait(false)) { response.Content.Headers.TryGetValues("content-type", out var contentTypes); @@ -149,54 +190,5 @@ private static HttpResponseMessage ReturnHttpResponseMessage(HttpStatusCode http return httpResponseMessage; } - - private string GetBaseUrlWithoutVersion(GraphServiceClient graphClient) - { - var baseUrl = graphClient.BaseUrl; - var index = baseUrl.LastIndexOf('/'); - return baseUrl.Substring(0, index); - } - - public class HttpResponseMessageResult : IActionResult - { - private readonly HttpResponseMessage _responseMessage; - - public HttpResponseMessageResult(HttpResponseMessage responseMessage) - { - _responseMessage = responseMessage; // could add throw if null - } - - public async Task ExecuteResultAsync(ActionContext context) - { - context.HttpContext.Response.StatusCode = (int)_responseMessage.StatusCode; - - foreach (var header in _responseMessage.Headers) - { - context.HttpContext.Response.Headers.TryAdd(header.Key, new StringValues(header.Value.ToArray())); - } - - context.HttpContext.Response.ContentType = _responseMessage.Content.Headers.ContentType.ToString(); - - using (var stream = await _responseMessage.Content.ReadAsStreamAsync()) - { - await stream.CopyToAsync(context.HttpContext.Response.Body); - await context.HttpContext.Response.Body.FlushAsync(); - } - } - } - - [Route("api/[controller]/{*all}")] - [Route("graphproxy/{*all}")] - [HttpPatch] - [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task PatchAsync(string all, [FromBody] object body) - { - return await ProcessRequestAsync("PATCH", all, body).ConfigureAwait(false); - } - - private async Task ProcessRequestAsync(string method, string all, object content) - { - return Ok(); - } } } From 7095209c7e25e854ed4149e17ac0d2cfca5c2a1d Mon Sep 17 00:00:00 2001 From: Grace Tsao Date: Tue, 20 Jul 2021 02:13:21 -0700 Subject: [PATCH 3/8] Uses interface --- .../GraphExplorerAppModeService.csproj | 2 ++ .../Interfaces/IGraphAppAuthProvider.cs | 6 ++-- .../Services/GraphAppAuthProvider.cs | 14 ++++++-- .../GraphExplorerAppModeController.cs | 35 +++++++------------ GraphWebApi/Startup.cs | 3 ++ MSGraphWebApi.sln | 6 ++++ 6 files changed, 38 insertions(+), 28 deletions(-) diff --git a/GraphExplorerAppModeService/GraphExplorerAppModeService.csproj b/GraphExplorerAppModeService/GraphExplorerAppModeService.csproj index 522ad66e5..52b8f98f0 100644 --- a/GraphExplorerAppModeService/GraphExplorerAppModeService.csproj +++ b/GraphExplorerAppModeService/GraphExplorerAppModeService.csproj @@ -8,5 +8,7 @@ + + diff --git a/GraphExplorerAppModeService/Interfaces/IGraphAppAuthProvider.cs b/GraphExplorerAppModeService/Interfaces/IGraphAppAuthProvider.cs index 669e3feeb..56198c228 100644 --- a/GraphExplorerAppModeService/Interfaces/IGraphAppAuthProvider.cs +++ b/GraphExplorerAppModeService/Interfaces/IGraphAppAuthProvider.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.Graph; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,7 +7,8 @@ namespace GraphExplorerAppModeService.Interfaces { - interface IGraphAppAuthProvider + public interface IGraphAppAuthProvider { + GraphServiceClient GetAuthenticatedGraphClient(string accessToken); } } diff --git a/GraphExplorerAppModeService/Services/GraphAppAuthProvider.cs b/GraphExplorerAppModeService/Services/GraphAppAuthProvider.cs index 67f55c01a..877ebea9c 100644 --- a/GraphExplorerAppModeService/Services/GraphAppAuthProvider.cs +++ b/GraphExplorerAppModeService/Services/GraphAppAuthProvider.cs @@ -1,8 +1,11 @@ using GraphExplorerAppModeService.Interfaces; using Microsoft.Extensions.Configuration; +using Microsoft.Graph; +using Microsoft.Identity.Web; using System; using System.Collections.Generic; using System.Linq; +using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; @@ -11,9 +14,14 @@ namespace GraphExplorerAppModeService.Services { public class GraphAppAuthProvider : IGraphAppAuthProvider { - public GraphAppAuthProvider(IConfiguration configuration) - { - } + public GraphServiceClient GetAuthenticatedGraphClient(string accessToken) => + new GraphServiceClient(new DelegateAuthenticationProvider( + async requestMessage => + { + // Append the access token to the request + requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + })); } + } diff --git a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs index cebaff3ed..90cb906df 100644 --- a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs +++ b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs @@ -14,18 +14,20 @@ using Microsoft.Identity.Client; using System.Threading; using Microsoft.Extensions.Primitives; +using GraphExplorerAppModeService.Services; namespace GraphWebApi.Controllers { [ApiController] public class GraphExplorerAppModeController : ControllerBase { - private readonly ITokenAcquisition tokenAcquisition; - private readonly GraphServiceClient _graphServiceClient; - public GraphExplorerAppModeController(ITokenAcquisition tokenAcquisition, GraphServiceClient graphServiceClient) + private readonly IGraphAppAuthProvider _graphClient; + private readonly ITokenAcquisition _tokenAcquisition; + + public GraphExplorerAppModeController(ITokenAcquisition tokenAcquisition, IGraphAppAuthProvider graphServiceClient) { - this.tokenAcquisition = tokenAcquisition; - this._graphServiceClient = graphServiceClient; + this._graphClient = graphServiceClient; + this._tokenAcquisition = tokenAcquisition; } [Route("api/[controller]/{*all}")] [Route("graphproxy/{*all}")] @@ -36,17 +38,14 @@ public async Task GetAsync(string all) return await this.ProcessRequestAsync("GET", all, null).ConfigureAwait(false); } - [Route("api/[controller]/{*all}")] - [Route("graphproxy/token")] - [HttpGet] - [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task GetTokenAsync(string all) + private async Task GetTokenAsync() { // Acquire the access token. string scopes = "https://graph.microsoft.com/.default"; - return await tokenAcquisition.GetAccessTokenForAppAsync(scopes); - } + return await _tokenAcquisition.GetAccessTokenForAppAsync(scopes); + } + [Route("api/[controller]/{*all}")] [Route("graphproxy/{*all}")] @@ -121,22 +120,12 @@ public async Task PatchAsync(string all, [FromBody] object body) private async Task ProcessRequestAsync(string method, string all, object content) { - GraphServiceClient _graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider( - async requestMessage => - { - // Passing tenant ID to the sample auth provider to use as a cache key - string accessToken = GetTokenAsync("").Result.ToString(); - // Append the access token to the request - requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - })); + GraphServiceClient _graphServiceClient = _graphClient.GetAuthenticatedGraphClient(GetTokenAsync().Result.ToString()); var qs = HttpContext.Request.QueryString; - Console.WriteLine(HttpContext); var url = $"{GetBaseUrlWithoutVersion(_graphServiceClient)}/{all}{qs.ToUriComponent()}"; - Console.WriteLine("IS IT IN HERE"); - var request = new BaseRequest(url, _graphServiceClient, null) { Method = method, diff --git a/GraphWebApi/Startup.cs b/GraphWebApi/Startup.cs index f63d2c7fe..486b09b6b 100644 --- a/GraphWebApi/Startup.cs +++ b/GraphWebApi/Startup.cs @@ -30,6 +30,8 @@ using System.Threading.Tasks; using Microsoft.Identity.Web; using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using GraphExplorerAppModeService.Services; +using GraphExplorerAppModeService.Interfaces; namespace GraphWebApi { @@ -102,6 +104,7 @@ public void ConfigureServices(IServiceCollection services) services.AddMemoryCache(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/MSGraphWebApi.sln b/MSGraphWebApi.sln index 95c992d8c..94b2d4332 100644 --- a/MSGraphWebApi.sln +++ b/MSGraphWebApi.sln @@ -43,6 +43,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UtilityService", "UtilitySe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UtilityService.Test", "UtilityService.Test\UtilityService.Test.csproj", "{0F4A15DC-F4CD-415D-A62D-6B0D95ED25E8}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphExplorerAppModeService", "GraphExplorerAppModeService\GraphExplorerAppModeService.csproj", "{215188E9-27A7-4004-B6FA-5A1C0D5786BF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -129,6 +131,10 @@ Global {0F4A15DC-F4CD-415D-A62D-6B0D95ED25E8}.Debug|Any CPU.Build.0 = Debug|Any CPU {0F4A15DC-F4CD-415D-A62D-6B0D95ED25E8}.Release|Any CPU.ActiveCfg = Release|Any CPU {0F4A15DC-F4CD-415D-A62D-6B0D95ED25E8}.Release|Any CPU.Build.0 = Release|Any CPU + {215188E9-27A7-4004-B6FA-5A1C0D5786BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {215188E9-27A7-4004-B6FA-5A1C0D5786BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {215188E9-27A7-4004-B6FA-5A1C0D5786BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {215188E9-27A7-4004-B6FA-5A1C0D5786BF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From e452f8f014b83530adfc5dcc47eda26c2539b77b Mon Sep 17 00:00:00 2001 From: Grace Tsao Date: Tue, 20 Jul 2021 11:19:00 -0700 Subject: [PATCH 4/8] Removed console.writeline --- GraphWebApi/Controllers/GraphExplorerAppModeController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs index 90cb906df..9505ee8e3 100644 --- a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs +++ b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs @@ -53,7 +53,6 @@ private async Task GetTokenAsync() [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] public async Task PostAsync(string all, [FromBody] object body) { - Console.WriteLine(body); return await ProcessRequestAsync("POST", all, body).ConfigureAwait(false); } From b2701848519d6ad5d643c0407cb48f8b183fb024 Mon Sep 17 00:00:00 2001 From: Grace Tsao Date: Wed, 21 Jul 2021 16:44:01 -0700 Subject: [PATCH 5/8] Extracted the tenantId --- .../GraphExplorerAppModeController.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs index 9505ee8e3..da2d5b584 100644 --- a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs +++ b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; -using GraphExplorerAppModeService.Interfaces; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -15,6 +14,7 @@ using System.Threading; using Microsoft.Extensions.Primitives; using GraphExplorerAppModeService.Services; +using GraphExplorerAppModeService.Interfaces; namespace GraphWebApi.Controllers { @@ -30,47 +30,47 @@ public GraphExplorerAppModeController(ITokenAcquisition tokenAcquisition, IGraph this._tokenAcquisition = tokenAcquisition; } [Route("api/[controller]/{*all}")] - [Route("graphproxy/{*all}")] + [Route("graphproxy/{tenantId}/{*all}")] [HttpGet] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task GetAsync(string all) + public async Task GetAsync(string all, string tenantId) { - return await this.ProcessRequestAsync("GET", all, null).ConfigureAwait(false); + return await this.ProcessRequestAsync("GET", all, null, tenantId).ConfigureAwait(false); } - private async Task GetTokenAsync() + private async Task GetTokenAsync(string tenantId) { // Acquire the access token. string scopes = "https://graph.microsoft.com/.default"; - return await _tokenAcquisition.GetAccessTokenForAppAsync(scopes); + return await _tokenAcquisition.GetAccessTokenForAppAsync(scopes, tenantId, null); } [Route("api/[controller]/{*all}")] - [Route("graphproxy/{*all}")] + [Route("graphproxy/{tenantId}/{*all}")] [HttpPost] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task PostAsync(string all, [FromBody] object body) + public async Task PostAsync(string all, [FromBody] object body, string tenantId) { - return await ProcessRequestAsync("POST", all, body).ConfigureAwait(false); + return await ProcessRequestAsync("POST", all, body, tenantId).ConfigureAwait(false); } [Route("api/[controller]/{*all}")] - [Route("graphproxy/{*all}")] + [Route("graphproxy/{tenantId}/{*all}")] [HttpDelete] - public async Task DeleteAsync(string all) + public async Task DeleteAsync(string all, string tenantId) { - return await ProcessRequestAsync("DELETE", all, null).ConfigureAwait(false); + return await ProcessRequestAsync("DELETE", all, null, tenantId).ConfigureAwait(false); } [Route("api/[controller]/{*all}")] - [Route("graphproxy/{*all}")] + [Route("graphproxy/{tenantId}/{*all}")] [HttpPut] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task PutAsync(string all, [FromBody] object body) + public async Task PutAsync(string all, [FromBody] object body, string tenantId) { - return await ProcessRequestAsync("PUT", all, body).ConfigureAwait(false); + return await ProcessRequestAsync("PUT", all, body, tenantId).ConfigureAwait(false); } private string GetBaseUrlWithoutVersion(GraphServiceClient graphClient) @@ -109,17 +109,17 @@ public async Task ExecuteResultAsync(ActionContext context) } [Route("api/[controller]/{*all}")] - [Route("graphproxy/{*all}")] + [Route("graphproxy/{tenantId}/{*all}")] [HttpPatch] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task PatchAsync(string all, [FromBody] object body) + public async Task PatchAsync(string all, [FromBody] object body, string tenantId) { - return await ProcessRequestAsync("PATCH", all, body).ConfigureAwait(false); + return await ProcessRequestAsync("PATCH", all, body, tenantId).ConfigureAwait(false); } - private async Task ProcessRequestAsync(string method, string all, object content) + private async Task ProcessRequestAsync(string method, string all, object content, string tenantId) { - GraphServiceClient _graphServiceClient = _graphClient.GetAuthenticatedGraphClient(GetTokenAsync().Result.ToString()); + GraphServiceClient _graphServiceClient = _graphClient.GetAuthenticatedGraphClient(GetTokenAsync(tenantId).Result.ToString()); var qs = HttpContext.Request.QueryString; From f71c98b88cfb2adebbfc2ecc6cbc160b3d843055 Mon Sep 17 00:00:00 2001 From: Grace Tsao Date: Wed, 21 Jul 2021 16:53:48 -0700 Subject: [PATCH 6/8] Updated MSGraphWebApi.sln so that it is unchanged --- MSGraphWebApi.sln | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MSGraphWebApi.sln b/MSGraphWebApi.sln index 94b2d4332..600414ab3 100644 --- a/MSGraphWebApi.sln +++ b/MSGraphWebApi.sln @@ -43,7 +43,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UtilityService", "UtilitySe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UtilityService.Test", "UtilityService.Test\UtilityService.Test.csproj", "{0F4A15DC-F4CD-415D-A62D-6B0D95ED25E8}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphExplorerAppModeService", "GraphExplorerAppModeService\GraphExplorerAppModeService.csproj", "{215188E9-27A7-4004-B6FA-5A1C0D5786BF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphExplorerAppModeService", "GraphExplorerAppModeService\GraphExplorerAppModeService.csproj", "{AF515BB3-08B5-41A1-80E6-4529670A6B1C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -131,10 +131,10 @@ Global {0F4A15DC-F4CD-415D-A62D-6B0D95ED25E8}.Debug|Any CPU.Build.0 = Debug|Any CPU {0F4A15DC-F4CD-415D-A62D-6B0D95ED25E8}.Release|Any CPU.ActiveCfg = Release|Any CPU {0F4A15DC-F4CD-415D-A62D-6B0D95ED25E8}.Release|Any CPU.Build.0 = Release|Any CPU - {215188E9-27A7-4004-B6FA-5A1C0D5786BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {215188E9-27A7-4004-B6FA-5A1C0D5786BF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {215188E9-27A7-4004-B6FA-5A1C0D5786BF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {215188E9-27A7-4004-B6FA-5A1C0D5786BF}.Release|Any CPU.Build.0 = Release|Any CPU + {AF515BB3-08B5-41A1-80E6-4529670A6B1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF515BB3-08B5-41A1-80E6-4529670A6B1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF515BB3-08B5-41A1-80E6-4529670A6B1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF515BB3-08B5-41A1-80E6-4529670A6B1C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 3794493386e404e5831c2b2da251da8a3d767c8d Mon Sep 17 00:00:00 2001 From: Grace Tsao Date: Thu, 22 Jul 2021 11:08:05 -0700 Subject: [PATCH 7/8] Removed tenantId from the api call --- .../GraphExplorerAppModeController.cs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs index da2d5b584..de4593b3c 100644 --- a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs +++ b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs @@ -15,6 +15,7 @@ using Microsoft.Extensions.Primitives; using GraphExplorerAppModeService.Services; using GraphExplorerAppModeService.Interfaces; +using Microsoft.Extensions.Configuration; namespace GraphWebApi.Controllers { @@ -24,18 +25,21 @@ public class GraphExplorerAppModeController : ControllerBase private readonly IGraphAppAuthProvider _graphClient; private readonly ITokenAcquisition _tokenAcquisition; - public GraphExplorerAppModeController(ITokenAcquisition tokenAcquisition, IGraphAppAuthProvider graphServiceClient) + private readonly IConfiguration _config; + + public GraphExplorerAppModeController(IConfiguration configuration, ITokenAcquisition tokenAcquisition, IGraphAppAuthProvider graphServiceClient) { this._graphClient = graphServiceClient; this._tokenAcquisition = tokenAcquisition; + this._config = configuration; } [Route("api/[controller]/{*all}")] - [Route("graphproxy/{tenantId}/{*all}")] + [Route("graphproxy/{*all}")] [HttpGet] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] public async Task GetAsync(string all, string tenantId) { - return await this.ProcessRequestAsync("GET", all, null, tenantId).ConfigureAwait(false); + return await this.ProcessRequestAsync("GET", all, null, _config.GetSection("AzureAd").GetSection("TenantId").Value).ConfigureAwait(false); } private async Task GetTokenAsync(string tenantId) @@ -48,29 +52,29 @@ private async Task GetTokenAsync(string tenantId) [Route("api/[controller]/{*all}")] - [Route("graphproxy/{tenantId}/{*all}")] + [Route("graphproxy/{*all}")] [HttpPost] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] public async Task PostAsync(string all, [FromBody] object body, string tenantId) { - return await ProcessRequestAsync("POST", all, body, tenantId).ConfigureAwait(false); + return await ProcessRequestAsync("POST", all, body, _config.GetSection("AzureAd").GetSection("TenantId").Value).ConfigureAwait(false); } [Route("api/[controller]/{*all}")] - [Route("graphproxy/{tenantId}/{*all}")] + [Route("graphproxy/{*all}")] [HttpDelete] public async Task DeleteAsync(string all, string tenantId) { - return await ProcessRequestAsync("DELETE", all, null, tenantId).ConfigureAwait(false); + return await ProcessRequestAsync("DELETE", all, null, _config.GetSection("AzureAd").GetSection("TenantId").Value).ConfigureAwait(false); } [Route("api/[controller]/{*all}")] - [Route("graphproxy/{tenantId}/{*all}")] + [Route("graphproxy/{*all}")] [HttpPut] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] public async Task PutAsync(string all, [FromBody] object body, string tenantId) { - return await ProcessRequestAsync("PUT", all, body, tenantId).ConfigureAwait(false); + return await ProcessRequestAsync("PUT", all, body, _config.GetSection("AzureAd").GetSection("TenantId").Value).ConfigureAwait(false); } private string GetBaseUrlWithoutVersion(GraphServiceClient graphClient) @@ -109,12 +113,12 @@ public async Task ExecuteResultAsync(ActionContext context) } [Route("api/[controller]/{*all}")] - [Route("graphproxy/{tenantId}/{*all}")] + [Route("graphproxy/{*all}")] [HttpPatch] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] public async Task PatchAsync(string all, [FromBody] object body, string tenantId) { - return await ProcessRequestAsync("PATCH", all, body, tenantId).ConfigureAwait(false); + return await ProcessRequestAsync("PATCH", all, body, _config.GetSection("AzureAd").GetSection("TenantId").Value).ConfigureAwait(false); } private async Task ProcessRequestAsync(string method, string all, object content, string tenantId) From b3869bd0cdfa9022066be130e46c90538e78c65b Mon Sep 17 00:00:00 2001 From: Grace Tsao Date: Thu, 22 Jul 2021 11:31:12 -0700 Subject: [PATCH 8/8] Removed tenantId from parameters --- .../Controllers/GraphExplorerAppModeController.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs index de4593b3c..d68e08040 100644 --- a/GraphWebApi/Controllers/GraphExplorerAppModeController.cs +++ b/GraphWebApi/Controllers/GraphExplorerAppModeController.cs @@ -37,7 +37,7 @@ public GraphExplorerAppModeController(IConfiguration configuration, ITokenAcquis [Route("graphproxy/{*all}")] [HttpGet] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task GetAsync(string all, string tenantId) + public async Task GetAsync(string all) { return await this.ProcessRequestAsync("GET", all, null, _config.GetSection("AzureAd").GetSection("TenantId").Value).ConfigureAwait(false); } @@ -55,7 +55,7 @@ private async Task GetTokenAsync(string tenantId) [Route("graphproxy/{*all}")] [HttpPost] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task PostAsync(string all, [FromBody] object body, string tenantId) + public async Task PostAsync(string all, [FromBody] object body) { return await ProcessRequestAsync("POST", all, body, _config.GetSection("AzureAd").GetSection("TenantId").Value).ConfigureAwait(false); } @@ -63,7 +63,7 @@ public async Task PostAsync(string all, [FromBody] object body, s [Route("api/[controller]/{*all}")] [Route("graphproxy/{*all}")] [HttpDelete] - public async Task DeleteAsync(string all, string tenantId) + public async Task DeleteAsync(string all) { return await ProcessRequestAsync("DELETE", all, null, _config.GetSection("AzureAd").GetSection("TenantId").Value).ConfigureAwait(false); } @@ -72,7 +72,7 @@ public async Task DeleteAsync(string all, string tenantId) [Route("graphproxy/{*all}")] [HttpPut] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task PutAsync(string all, [FromBody] object body, string tenantId) + public async Task PutAsync(string all, [FromBody] object body) { return await ProcessRequestAsync("PUT", all, body, _config.GetSection("AzureAd").GetSection("TenantId").Value).ConfigureAwait(false); } @@ -116,7 +116,7 @@ public async Task ExecuteResultAsync(ActionContext context) [Route("graphproxy/{*all}")] [HttpPatch] [AuthorizeForScopes(Scopes = new[] { "https://graph.microsoft.com/.default" })] - public async Task PatchAsync(string all, [FromBody] object body, string tenantId) + public async Task PatchAsync(string all, [FromBody] object body) { return await ProcessRequestAsync("PATCH", all, body, _config.GetSection("AzureAd").GetSection("TenantId").Value).ConfigureAwait(false); }