Search code examples
.net-coreapache2cloudflareblazor-server-sideasp.net-core-3.1

IHttpContextAccessor.HttpContext is null in in production environment


I have a Blazor Server app that behaves differently in development and production. The problem is, that in production the HttpContext is always null in the service classes

All Service classes derive from a BaseService class. In the constructor are all dependencies injected. Also the IHttpContextAccessor.

BaseService.cs

//Condensed down...
public abstract class BaseService
{    
    private IHttpContextAccessor _httpContextAccessor;      
    protected HttpContext HttpContext { get { return _httpContextAccessor.HttpContext; } }

    protected BaseService(IConfiguration configuration,
                          UserManager<MyProjectIdentityUser> userManager,
                          IHttpContextAccessor httpContextAccessor,
                          Repositories.MyDbContext dbContext,
                          ILogger<object> logger)
    {
        //...
        _httpContextAccessor = httpContextAccessor;
        //...
    }

    public async Task<MyProjectIdentityUser> GetUserAsync()
    {
        //Here is the HttpContext always null...
        var user = await UserManager.FindByIdAsync(HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value);
        return user;
    }
}

Whenever I need the current user in one of the service classes, I call var user = GetUserAsync(); and get it.

This implementation works perfectly when I debug the application in visual studio, but in production, I can't access the HttpContext. The production environment is a combination of Ubuntu 18, Apache2 and Cloudflare.

At the moment, I don't have an idea of where to start looking. Everything else in production works also. As long as I don't try to access the HttpContext.


Solution

  • As I suspected, there was no problem with the code, but with the environment. It could not be a WebSocket connection established. This needs some config in the Apache2 server

    1. All required modules must be enabled. In my case it was rewrite proxy_wstunnel I had to enable with.

      a2enmod rewrite    
      a2enmod proxy_wstunnel
      
    2. The .conf for the application

      ProxyPreserveHost On
      ProxyPass / http://127.0.0.1:5000/
      ProxyPassReverse / http://127.0.0.1:5000/
      
      RewriteEngine on
      RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
      RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
      RewriteRule /(.*) ws://127.0.0.1:5000/$1 [P]
      

    Now the HttpContext is available.