1

I am having an issue with users and autofac. I followed a guide that said to get the current user to use in your services, you must first create a wrapper class like this:

public class PrincipalProvider : IPrincipalProvider
{
    public IPrincipal User => HttpContext.Current?.User;
}

And then you need to register it as PerDependency in your module like this:

builder.RegisterType<PrincipalProvider>().As<IPrincipalProvider>().InstancePerDependency();

Then I have a simple controller:

private readonly IHealthCheckProvider _healthCheckProvider;

/// <summary>
/// Default constructor
/// </summary>
/// <param name="healthCheckProvider">The provider used to do health checks</param>
public HealthCheckController(IHealthCheckProvider healthCheckProvider)
{
    _healthCheckProvider = healthCheckProvider;
}

/// <summary>
/// Lists all the current services and their status details
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("")]
public async Task<IHttpActionResult> ListAsync() => Ok(await _healthCheckProvider.ListAsync());

The healthcheck provider has the principal provider injected into it and the list method tries to get the current user:

private readonly CormarConfig _config;
private readonly IHealthCheckService _healthCheckService;
private readonly IUnitOfWork _unitOfWork;

private readonly Lazy<IPrincipalProvider> _principalProvider;

public HealthCheckProvider(IUnitOfWork unitOfWork, CormarConfig config, IHealthCheckService healthCheckService, Lazy<IPrincipalProvider> principalProvider)
{
    _unitOfWork = unitOfWork;
    _config = config;
    _healthCheckService = healthCheckService;

    _principalProvider = principalProvider;
}

public async Task<IList<HealthCheck>> ListAsync()
{
    var models = await _healthCheckService.List().ToListAsync();
    var user = _principalProvider.Value.User;
    return models;
}

The problem I have is that the user is always null. Does anyone know how I can solve this?

And just for reference sake, here is my config method in the StartupConfig.cs class:

public void Configuration(IAppBuilder app)
{

    // Cors must be first, or it will not work
    app.UseCors(CorsOptions.AllowAll);
    CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");

    // Get our configuration
    var config = new HttpConfiguration();
    var container = ConfigureInversionOfControl(app, config);
    var scope = config.DependencyResolver.GetRootLifetimeScope();
    var serverOptions = ConfigureOAuthTokenGeneration(app, scope);

    // Configur our application
    ConfigureOAuthTokenConsumption(app);
    ConfigureWebApi(config, scope);

    // Register the Autofac middleware FIRST. This also adds
    // Autofac-injected middleware registered with the container.
    app.UseAutofacMiddleware(container);
    app.UseAutofacWebApi(config);
    app.UseOAuthAuthorizationServer(serverOptions);
    app.UseWebApi(config);
}

I don't think anything is wrong in there, but you never know.

r3plica
  • 13,017
  • 23
  • 128
  • 290
  • Put a breakpoint on your `public IPrincipal User => HttpContext.Current?.User;` line and see what's null etc, or even if it is being hit. Do you ever build your container? I can't see it in your code sample. – Paul Suart Jul 28 '17 at 14:30
  • the context seems to be always null. Yeah I do build, it's later on. I have stripped out most of the code to make things simpler – r3plica Jul 28 '17 at 15:01
  • Are you using OWIN hosting? I don't believe `HttpContext.Current` is what you want to use if you are. If you're OWIN-hosted, see this answer: https://stackoverflow.com/a/24572864/68432 – Paul Suart Jul 28 '17 at 15:07
  • r3plica, did you get this working? – Paul Suart Aug 04 '17 at 09:53
  • Not really, no. It works as long as the service that I inject this into is injected into a controller. A nested service doesn't have access to the HttpContext. – r3plica Aug 11 '17 at 11:27
  • Looking at it again, httpcontext.current is threadstatic and you're accessing it directly after an "await" call (await _healthCheckService.List().ToListAsync();). Try making that line synchronous (or just remove or reorder the lines to test)....? – Paul Suart Aug 11 '17 at 12:49

0 Answers0