C# 如何在.Net core 2.0中从HttpContext获取访问令牌

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

我正在尝试将一个项目从.Net core 1.1升级到.Net core 2.0。有很多突破性的更改。我目前遇到的一个问题是,
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;