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

103,504

Solution 1

It ended up being a configuration issue. There needs to be a link between AddAuthentication and AddOpenIdConnect in order for it to read the cookie into the headers.

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

Controller

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

Access token is now populated.

Note: I ended up digging it out of this project Startup.cs

Solution 2

.Net core 2.1 to access JWT bearer token

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

Solution 3

In Controller, the token can be retrieved by reading Request.Headers dictionary:

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

At other classes where HttpContext is not available, there token can be retrieved using HttpContextAccessor after injecting into services collection ( A little change from Azharuddin answer)

Register the service instance in Startup method like

public void ConfigureServices(IServiceCollection services)
{

 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
 ...
}

And inject the dependency in your controller like

private IHttpContextAccessor _httpContextAccessor;
public ClientController(IHttpContextAccessor httpContextAccessor)
{
     _httpContextAccessor = httpContextAccessor;
}

And retrieve the access token in your action like

[Authorize]
public async Task<IActionResult> ClientUpdate(ClientModel client)
{
    var accessToken = _httpContextAccessor.HttpContext.Request.Headers["Authorization"];

    ..........//Some other code
    return View();
}

Solution 4

Startup.cs:

 public void ConfigureServices(IServiceCollection services)
 {
    ...
     services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    ...
 }

Controller Constructor:

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

This should work

Share:
103,504
DaImTo
Author by

DaImTo

Google Developer Expert for Google Analytics and Identity platform I have been working with Google APIs since 2012. ⬇️ My Youtube Channel with lots of Google API tutorials ⬇️ 🔔 YouTube Channel: https://www.youtube.com/channel/UCyqzvMN8newXIxyYIkFzPvA Daimto.com https://www.daimto.com I enjoy working with Google's APIs and have experience with Google OAuth2, Google Analytics API, Google+ API, Google Calendar API, YouTube API, BigQuery API and Google Drive SDK. Projects: Contributor Google APIs .Net Client Library, Identity Server 4 Author of the Google-dotnet-sample project on GitHub

Updated on July 05, 2022

Comments

  • DaImTo
    DaImTo almost 2 years

    I'm trying to upgrade a project from .Net core 1.1 to .Net core 2.0 there's a lot of breaking changes.

    One of the things I'm currently having an issue with is that HttpContext.Authentication is now obsolete.

    I've been trying to figure out how to get the Access token for the current request. I need to make a call to another API which requires a bearer token.

    Old Method .Net core 1.1

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

    Method .Net core 2.0

    This is not working becouse context isnt registered.

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

    Unable to resolve service for type 'Microsoft.AspNetCore.Http.HttpContext'

    I tried registering it but that doesnt work either

    public ConsoleController(IOptions<ServiceSettings> serviceSettings, HttpContext context) 
    

    In startup.cs

    services.TryAddSingleton<HttpContext, HttpContext>();
    

    Update:

    This returns null

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

    Startup.cs ConfigureServices

    I wouldn't be surprised if it was something in the startup as there were a lot of breaking changes here as well.

    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 Configure

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