我正在尝试将项目从.Net核心1.1升级到.Net核心2.0,有很多重大变化。我目前遇到的一个问题是HttpContext.Authentication
现在已经过时了。
我一直在试图弄清楚如何获取当前请求的Access令牌。我需要调用另一个需要持有令牌的API。
旧方法.Net核心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?}");
});
答案 0 :(得分:23)
.Net core 2.1 访问JWT承载者令牌
var accesToken = Request.Headers["Authorization"];
答案 1 :(得分:14)
最终成为配置问题。 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 :(得分:12)
如果您想要纯令牌,则可以在.net core 3.1中提供帮助
var _bearer_token = Request.Headers[HeaderNames.Authorization].ToString().Replace("Bearer ", "");
,请记住,您需要使用来添加
using Microsoft.Net.Http.Headers;
答案 3 :(得分:3)
Azharuddin的回答有点变化
在启动方法中注册服务实例,如
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 :(得分:2)
Startup.cs
DELIMITER $$
DROP PROCEDURE IF EXISTS check_status$$
CREATE PROCEDURE check_status()
BEGIN
DECLARE dd DATE;
DECLARE bDone INT;
DECLARE Count INT;
DEClARE my_status CURSOR FOR SELECT dates FROM t_date;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
OPEN my_status;
SET bDone = 0;
REPEAT
FETCH my_status INTO dd;
IF (dd < DATE(NOW()))
UPDATE t_date SET (status_number) VALUES (1);
END IF;
UNTIL bDone END REPEAT;
CLOSE my_status;
END$$
DELIMITER ;
Controller.cs构造函数
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
...
}
这应该有效
答案 5 :(得分:0)
非常感谢,这太完美了!
我有这项工作,但是有了我们的青睐租户的授权。只需用您的租户名称替换******。
options.Authority = "https://login.microsoftonline.com/******.onmicrosoft.com";
您还可以使用租户ID。只需在https://login.microsoftonline.com/
之后插入您的租户IDoptions.Authority = "https://login.microsoftonline.com/be0be093-****-****-****-5626e83beefc";
答案 6 :(得分:0)
您需要指定外部架构来检索令牌。
var accessToken = await HttpContext.GetTokenAsync(IdentityConstants.ExternalScheme, "access_token");