簡體   English   中英

如何從.Net core 2.0中的HttpContext獲取訪問令牌

[英]How to get access token from HttpContext in .Net core 2.0

我正在嘗試將項目從 .Net core 1.1 升級到 .Net core 2.0,其中有很多重大更改。

我目前遇到的問題之一是HttpContext.Authentication現在已過時。

我一直在試圖弄清楚如何獲取當前請求的訪問令牌。 我需要撥打另一個需要不記名令牌的 API。

舊方法.Net 核心 1.1

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

方法網核心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 配置服務

如果這是初創公司的事情,我不會感到驚訝,因為這里也有很多重大變化。

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?}");
});

.Net core 2.1訪問 JWT 不記名令牌

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

如果您想要純令牌,這可以在 .net core 3.1 中為您提供幫助

var _bearer_token = Request.Headers[HeaderNames.Authorization].ToString().Replace("Bearer ", "");

並記住你需要添加這個使用

using Microsoft.Net.Http.Headers;

它最終成為一個配置問題。 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中挖掘出來

在 Controller 中,可以通過讀取Request.Headers字典來檢索令牌:

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

在 HttpContext 不可用的其他類中,可以在注入服務集合后使用HttpContextAccessor檢索令牌(與 Azharuddin 回答稍有變化)

在 Startup 方法中注冊服務實例,例如

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();
}

啟動.cs:

 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 = await _httpContextAccessor.HttpContext.GetTokenAsync("access_token");
    return View();
}

這應該工作

您需要指定外部架構來檢索令牌。

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

非常感謝,這是完美的!

我有這項工作,但有我們天藍色的租戶專用權限。 只需將 ****** 替換為您的租戶名稱。

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

您還可以使用租戶 ID。 只需在https://login.microsoftonline.com/之后插入您的租戶 ID

options.Authority = "https://login.microsoftonline.com/be0be093-****-****-****-5626e83beefc";
string accessToken = Request.Headers[HeaderNames.Authorization].ToString().Replace($"{JwtBearerDefaults.AuthenticationScheme} ", String.Empty);

它應該是HttpContext.GetTokenAsync("access_token").Result.ToString();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM