Используйте внедрение зависимости, чтобы передать получение токена из startup.cs в HomeController.cs - PullRequest
0 голосов
/ 05 августа 2020

Я пытаюсь создать DI для следующего кода из файла Startup.cs. Но я новичок в. net Мне сложно найти решение.

var tokenAcquisition = context.HttpContext.RequestServices
     .GetRequiredService<ITokenAcquisition>() as ITokenAcquisition;

var graphClient = GraphServiceClientFactory
    .GetAuthenticatedGraphClient(async () =>
    {
        return await tokenAcquisition
            .GetAccessTokenForUserAsync(GraphConstants.Scopes);
    }
);

Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
using Microsoft.Identity.Web.UI;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.Graph;
using System.Net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace AD_Lookup
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages().AddRazorRuntimeCompilation();
            // Add Microsoft Identity Platform sign-in
            services.AddSignIn(options =>
            {
                Configuration.Bind("AzureAd", options);

                options.Prompt = "select_account";

                var authCodeHandler = options.Events.OnAuthorizationCodeReceived;
                options.Events.OnAuthorizationCodeReceived = async context => {
                    // Invoke the original handler first
                    // This allows the Microsoft.Identity.Web library to
                    // add the user to its token cache
                    await authCodeHandler(context);

                    var tokenAcquisition = context.HttpContext.RequestServices
                        .GetRequiredService<ITokenAcquisition>() as ITokenAcquisition;

                    var graphClient = GraphServiceClientFactory
                        .GetAuthenticatedGraphClient(async () =>
                        {
                            return await tokenAcquisition
                                .GetAccessTokenForUserAsync(GraphConstants.Scopes);
                        }
                    );

                    // Get user information from Graph
                    var user = await graphClient.Users["carvalhostephen20@hotmail.com"]
                        .Request()
                        .GetAsync();

                    context.Principal.AddUserGraphInfo(user);

                };


                options.Events.OnAuthenticationFailed = context => {
                    var error = WebUtility.UrlEncode(context.Exception.Message);
                    context.Response
                        .Redirect($"/Home/ErrorWithMessage?message=Authentication+error&debug={error}");
                    context.HandleResponse();

                    return Task.FromResult(0);
                };

                options.Events.OnRemoteFailure = context => {
                    if (context.Failure is OpenIdConnectProtocolException)
                    {
                        var error = WebUtility.UrlEncode(context.Failure.Message);
                        context.Response
                            .Redirect($"/Home/ErrorWithMessage?message=Sign+in+error&debug={error}");
                        context.HandleResponse();
                    }

                    return Task.FromResult(0);
                };
            }, options =>
            {
                Configuration.Bind("AzureAd", options);
            });

            

            // Add ability to call web API (Graph)
            // and get access tokens
            services.AddWebAppCallsProtectedWebApi(Configuration,
                GraphConstants.Scopes)
                // Use in-memory token cache
                // See https://github.com/AzureAD/microsoft-identity-web/wiki/token-cache-serialization
                .AddInMemoryTokenCaches();

            // Require authentication
            services.AddControllersWithViews(options =>
            {
                var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            })
            // Add the Microsoft Identity UI pages for signin/out
            .AddMicrosoftIdentityUI();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //if (env.IsDevelopment())
            //{
            //    app.UseDeveloperExceptionPage();
            //}
            //else
            //{
            //    app.UseExceptionHandler("/Home/Error");
            //    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            //    app.UseHsts();
            //}
            app.UseDeveloperExceptionPage();
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Homecontroller.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using AD_Lookup.Models;
using Microsoft.Graph;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
using Microsoft.Identity.Web.UI;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using System.Net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace AD_Lookup.Controllers
{

    public class HomeController : Controller
    {

    private readonly ILogger<HomeController> _logger;
        private ITokenAcquisition _tokenAcquisition;

        public HomeController(ILogger<HomeController> logger, ITokenAcquisition tokenAcquisition)
        {
            _logger = logger;
            _tokenAcquisition = tokenAcquisition;
        }


        public IActionResult Index()
        {
            return View();
        }

        
        public IActionResult UserSearch()
        {
            //string searchText = model.SearchBoxText;
            //ViewData["searchData"] = searchText;
            return View();
        }

        [HttpPost, ValidateAntiForgeryToken]
        public async Task<IActionResult> SearchBox(UserSearchModel model)
        {
            string searchText = model.SearchBoxText;
            ViewData["searchData"] = searchText;

            var tokenAcquisition = this.HttpContext.RequestServices
                    .GetRequiredService<ITokenAcquisition>() as ITokenAcquisition;

            var graphClient = GraphServiceClientFactory
                    .GetAuthenticatedGraphClient(async () =>
                    {
                        var accessToken =
 await tokenAcquisition.GetAccessTokenForUserAsync(GraphConstants.Scopes, "2b51e32f-e865-48ef-b075-0a456dc76468");
                        return accessToken;
                        //    .GetAccessTokenForUserAsync(GraphConstants.Scopes, "2b51e32f-e865-48ef-b075-0a456dc76468");
                    }
                );
            var user = await graphClient.Users[searchText]
                    .Request()
                    .GetAsync();

            return View();
            //return Content($"Hello {model.SearchBoxText}");
        }

        public IActionResult GroupSearch()
        {
            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

Вместо того, чтобы копировать тот же код в моем контроллере, я хочу передать значения токена, используя DI. текстовое окно. GraphAPI предоставляет следующий фрагмент кода, который я пытаюсь реализовать.

GraphServiceClient graphClient = new GraphServiceClient( authProvider );

var user = await graphClient.Users["carvalhostephen20@hotmail.com"]
    .Request()
    .GetAsync();

Его можно найти по адресу https://developer.microsoft.com/en-us/graph/graph-explorer Найдите пользователей с образцом запроса по электронной почте. Это функциональность, которую я пытаюсь реализовать.

Копирование кода Startup.cs в контроллер приводит к сбою решения и возврату следующей страницы ошибки: ErrorPage1

ErrorPage2

1 Ответ

2 голосов
/ 05 августа 2020

Извините, я впервые задаю вам неверный вопрос. Таким образом, вы регистрируете свой ITokenAcquisition, когда звоните services.AddWebAppCallsProtectedWebApi(). Попробуйте изменить свой Homecontroller. Удалите эту строку:

var tokenAcquisition = this.HttpContext.RequestServices
                .GetRequiredService<ITokenAcquisition>() as ITokenAcquisition;

И используйте вместо этого этот экземпляр: _tokenAcquisition

...