Как получить токен доступа из 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";