Как получить токен доступа из HttpContext в.Net core 2.0

Я пытаюсь обновить проект с.Net ядра 1.1 до.Net core 2.0, есть много изменений. Одна из вещей, с которыми HttpContext.Authentication сейчас HttpContext.Authentication заключается в том, что HttpContext.Authentication теперь устарела.

Я пытался выяснить, как получить токен доступа для текущего запроса. Мне нужно позвонить другому API, для которого требуется токен-носитель.

Старый метод.Net core 1.1

[Authorize]
public async Task<IActionResult> ClientUpdate(ClientModel client)
{
    var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");

    return View();
}

Метод.Net core 2.0

Это не работает, потому что контекст не зарегистрирован.

[Authorize]
public async Task<IActionResult> ClientUpdate(ClientModel client)
{
    var accessToken = await context.HttpContext.GetTokenAsync("access_token"); 

    return View();
}

Не удалось разрешить службу для типа "Microsoft.AspNetCore.Http.HttpContext"

Я попытался зарегистрировать его, но это не работает ни

public ConsoleController(IOptions<ServiceSettings> serviceSettings, HttpContext context) 

В startup.cs

services.TryAddSingleton<HttpContext, HttpContext>();

Обновить:

Это возвращает null

var accessToken = await HttpContext.GetTokenAsync("access_token");  

Startup.cs ConfigureServices

Я бы не удивился, если бы это было что-то в старте, так как здесь также было много нарушений.

services.Configure<ServiceSettings>(Configuration.GetSection("ServiceSettings"));
//services.TryAddSingleton<HttpContext, HttpContext>();
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddMvc();
services.AddAuthentication(options =>
            {

                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddCookie()
            .AddOpenIdConnect(options =>
            {
                options.Authority = "http://localhost:5000";
                options.ClientId = "testclient";
                options.ClientSecret = "secret";
                options.ResponseType = "code id_token";
                options.RequireHttpsMetadata = false;
                options.GetClaimsFromUserInfoEndpoint = true;
            });

Настроить Startup.cs

loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

        app.UseStaticFiles();
        app.UseAuthentication();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });

Ответы

Ответ 1

Это оказалось проблемой конфигурации. Должна быть связь между AddAuthentication и AddOpenIdConnect для того, чтобы он считывал cookie в заголовки.

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", options =>
            {
                options.SignInScheme = "Cookies";

                options.Authority = "http://localhost:5000";
                options.RequireHttpsMetadata = false;

                options.ClientId = "testclient";
                options.ClientSecret = "secret";
                options.ResponseType = "code id_token";
                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                options.Scope.Add("testapi");
                options.Scope.Add("offline_access");
            });

контроллер

    [Authorize]
    public async Task<IActionResult> Index()
    {
        var accessToken = await HttpContext.GetTokenAsync("access_token");
        return View();
    }

Токен доступа теперь заполнен.

Примечание: я закончил тем, что выкопал это из этого проекта Startup.cs

Ответ 2

.Net core 2.1 для доступа к токену-носителю JWT

var accessToken = Request.Headers["Authorization"];

Ответ 3

Небольшое изменение от Ажаруддина ответа

Зарегистрируйте экземпляр службы в методе запуска, как

public void ConfigureServices(IServiceCollection services)
{

 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
 ...
}

И внедрить зависимость в ваш контроллер, как

private IHttpContextAccessor _httpContextAccessor;
public ClientController(IHttpContextAccessor httpContextAccessor)
{
     _httpContextAccessor = httpContextAccessor;
}

И получить токен доступа в вашем действии, как

[Authorize]
public async Task<IActionResult> ClientUpdate(ClientModel client)
{
    var accessToken = _httpContextAccessor.HttpContext.Request.Headers["Authorization"];

    ..........//Some other code
    return View();
}

Ответ 4

Startup.cs

 public void ConfigureServices(IServiceCollection services)
    {
    ...
     services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
     ...
    }

Конструктор Controller.cs

private IHttpContextAccessor _httpContextAccessor;
public ClientController(IHttpContextAccessor httpContextAccessor)
{
     _httpContextAccessor = httpContextAccessor;
}



    [Authorize]
public async Task<IActionResult> ClientUpdate(ClientModel client)
{
    var accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync("access_token"); 

    return View();
}

Это должно работать

Ответ 5

Если access_token находится в заголовке запроса проверки подлинности, это был бы самый простой способ получить его

[Authorize]
public async Task<IActionResult> ClientUpdate(ClientModel client)
{
    var accessToken = Request.Headers["Authentication"];

    return View();
}

Ответ 6

Спасибо, это прекрасно!

У меня была эта работа, но с нашим лазурным арендатором. Просто замените ****** своим именем арендатора.

options.Authority = "https://login.microsoftonline.com/******.onmicrosoft.com";

Вы также можете использовать идентификатор арендатора. Просто введите свой идентификатор клиента после https://login.microsoftonline.com/

options.Authority = "https://login.microsoftonline.com/be0be093-****-****-****-5626e83beefc";