'HttpContext is returning null after an access token redirect (.NET 6.0)
I am trying to retrieve an access token and store it in a cookie through an authorization flow. The user is routed to the login portal of the 3rd party. After login, the user is then redirected back to my app however the HttpContext is lost in the redirect.
I am injecting IHttpContextAccessor into my service which works before the redirect, but after the login portal, it returns null.
public class ThirdPartyService: IThirdPartyApi
{
private string AccessToken;
private double ExpiresIn;
private readonly IServiceProvider _serviceProvider;
private IHttpContextAccessor _context;
public ThirdPartyService(IHttpContextAccessor context, IServiceProvider serviceProvider) {
_context = context;
_serviceProvider = serviceProvider;
}
public string CheckIfTokenIsValid()
{
var token = "";
var c = _context;
if (_context.HttpContext.Request.Cookies.TryGetValue("token", out token))
{
return token;
}
return token;
}
//Get Auth Code by Redirecting Users to Third Party Login Portal
public async Task<Task> GetAuthCode(string redirectUri)
{
var authClient = new RestClient(url);
var authRequest = new RestRequest();
authRequest.AddParameter("client_id", id);
authRequest.AddParameter("response_type", "code");
authRequest.AddParameter("redirect_uri", redirectUri); //Redirect after successful login
var authResponse = await authClient.ExecuteAsync(authRequest);
_context.HttpContext.Response.Redirect(authResponse.ResponseUri.AbsoluteUri, false);
return Task.CompletedTask;
}
//Get OAuth2 access token
public async void GetToken(string redirectUri, string code, string state)
{
var authClient = new RestClient(url);
var authRequest = new RestRequest();
authRequest.Method = Method.Post;
authRequest.AddParameter("client_id", id);
authRequest.AddParameter("client_secret", secret);
authRequest.AddParameter("code", code);
authRequest.AddParameter("grant_type", "authorization_code");
authRequest.AddParameter("redirect_uri", redirectUri);
var authResponse = await authClient.ExecuteAsync(authRequest);
AccessToken = JObject.Parse(authResponse.Content)["access_token"].Value<string>();
ExpiresIn = JObject.Parse(authResponse.Content)["expires_in"].Value<double>();
_context.HttpContext.Response.Cookies.Append("token", AccessToken, new Microsoft.AspNetCore.Http.CookieOptions { Expires = DateTime.Now.AddMinutes(ExpiresIn) });
_context.HttpContext.Response.Redirect(redirectUri);
}
}
GetToken() retrieves the token then redirects you back to the page you were on, but returns the error
Microsoft.AspNetCore.Http.IHttpContextAccessor.HttpContext.**get** returned null.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>(opt =>
opt.SignIn.RequireConfirmedEmail = true)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.AddScoped<ISTE, STEService>();
services.AddScoped<IPost, PostService>();
services.AddScoped<IUpload, UploadService>();
services.AddScoped<IApplicationUser, ApplicationUserService>();
services.AddScoped<IAdmin, AdminService>();
services.AddSingleton<IThirdPartyApi, ThirdPartyApi>();
services.AddSingleton(Configuration);
services.AddHttpContextAccessor();
services.AddSession();
//services.AddTransient<DataSeeder>();
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
//dataSeeder.SeedSuperUser().Wait();
app.UseStaticFiles();
app.UseSession();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
}
Am I just doing the flow incorrectly? How do I get around this bug? It has held up my production for 2 days.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
