C# 如何在.Net core 2.0中从HttpContext获取访问令牌
我正在尝试将一个项目从.Net core 1.1升级到.Net core 2.0。有很多突破性的更改。我目前遇到的一个问题是,C# 如何在.Net core 2.0中从HttpContext获取访问令牌,c#,http,asp.net-core,.net-core,C#,Http,Asp.net Core,.net Core,我正在尝试将一个项目从.Net core 1.1升级到.Net core 2.0。有很多突破性的更改。我目前遇到的一个问题是,HttpContext.Authentication现在已经过时了 我一直在试图找出如何获取当前请求的访问令牌。我需要调用另一个需要承载令牌的API 旧方法.Net core 1.1 [Authorize] public async Task<IActionResult> ClientUpdate(ClientModel client) { var a
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();
}
Startup.cs配置服务
如果这是初创公司的事情,我不会感到惊讶,因为这里也有很多突破性的变化
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
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
...
}
public void配置服务(IServiceCollection服务)
{
...
services.AddSingleton();
...
}
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();
}
专用IHttpContextAccessor\u httpContextAccessor;
公共客户端控制器(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor=httpContextAccessor;
}
[授权]
公共异步任务ClientUpdate(ClientModel客户端)
{
var accessToken=await_httpContextAccessor.HttpContext.GetTokenAsync(“访问令牌”);
返回视图();
}
这应该在控制器中起作用,可以通过读取
请求来检索令牌。标题字典:
var accessToken = Request.Headers["Authorization"];
在HttpContext不可用的其他类中,在注入服务集合后,可以使用HttpContextAccessor
检索令牌(
阿扎鲁丁的一点变化(答案)
在启动方法中注册服务实例,如
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
...
}
并在您的操作中检索访问令牌,如
[Authorize]
public async Task<IActionResult> ClientUpdate(ClientModel client)
{
var accessToken = _httpContextAccessor.HttpContext.Request.Headers["Authorization"];
..........//Some other code
return View();
}
[授权]
公共异步任务ClientUpdate(ClientModel客户端)
{
var accessToken=_httpContextAccessor.HttpContext.Request.Headers[“Authorization”];
……其他代码
返回视图();
}
它最终成为一个配置问题。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");
});
services.TryAddSingleton();
services.AddAuthentication(选项=>
{
options.DefaultScheme=“Cookies”;
options.DefaultChallengeScheme=“oidc”;
})
.AddCookie(“Cookies”)
.AddOpenIdConnect(“oidc”,选项=>
{
options.signnscheme=“Cookies”;
选项。权限=”http://localhost:5000";
options.RequireHttpsMetadata=false;
options.ClientId=“testclient”;
options.ClientSecret=“secret”;
options.ResponseType=“代码id\U令牌”;
options.SaveTokens=true;
options.GetClaimsFromUserInfoEndpoint=true;
选项。范围。添加(“testapi”);
options.Scope.Add(“脱机访问”);
});
控制器
[Authorize]
public async Task<IActionResult> Index()
{
var accessToken = await HttpContext.GetTokenAsync("access_token");
return View();
}
[授权]
公共异步任务索引()
{
var accessToken=await HttpContext.GetTokenAsync(“访问令牌”);
返回视图();
}
访问令牌现在已填充
注意:我最终从这个项目中挖掘了它
访问JWT承载令牌
var accessToken = Request.Headers[HeaderNames.Authorization];
真的谢谢,这太完美了
我有这项工作,但有我们azure租户的专门授权。只需将*******替换为您的租户名称即可
options.Authority = "https://login.microsoftonline.com/******.onmicrosoft.com";
您也可以使用租户id。只需在
您需要指定外部架构来检索令牌
var accessToken = await HttpContext.GetTokenAsync(IdentityConstants.ExternalScheme, "access_token");
如果您想要纯令牌,这可以在.net core 3.1中帮助您
var _bearer_token = Request.Headers[HeaderNames.Authorization].ToString().Replace("Bearer ", "");
请记住,您需要使用
using Microsoft.Net.Http.Headers;
您不必注册HttpContext
。它已经在控制器类中可用,就像在1.1中一样。@Brad这是我的想法,但我无法访问它。请描述您的意思。您的控制器是否继承自类controller
?如果GetAccessToken()
返回空值,则您的身份验证配置中可能存在问题。您在启动时是如何配置身份验证的?ClientUpdate位于同一控制台控制器中,因此我必须说是?您的控制器中不需要IHttpContextAccessor
。它已经作为HttpContext
属性存在。它是!您的配置不正确,这一回答清楚地表明了这一点。如果未填充HttpContext
,您将得到NullReferenceException
。这就是我所说的身份验证配置!我的标题怎么可能是空的?它传递了我的[Authorize]
属性,但是。。。是否可能在名为Cookie
的头中?@El Mac显然,我在Startup.ConfigureServices
中的AddOpenIdConnect
方法中缺少options.SaveTokens=true
。这不仅仅返回令牌。它还包括来自报头(“承载者”)的身份验证方案,因此如果您只想要令牌,则必须提取it@Tobias请求从何而来?我使用var-token=HttpContext.Request.Headers[“Authorization”][0]@user1672994做了一个小的打字错误,授权应该非常清晰。建议在try…catch下包装,但这是可选的。
[Authorize]
public async Task<IActionResult> Index()
{
var accessToken = await HttpContext.GetTokenAsync("access_token");
return View();
}
var accessToken = Request.Headers[HeaderNames.Authorization];
options.Authority = "https://login.microsoftonline.com/******.onmicrosoft.com";
options.Authority = "https://login.microsoftonline.com/be0be093-****-****-****-5626e83beefc";
var accessToken = await HttpContext.GetTokenAsync(IdentityConstants.ExternalScheme, "access_token");
var _bearer_token = Request.Headers[HeaderNames.Authorization].ToString().Replace("Bearer ", "");
using Microsoft.Net.Http.Headers;