Closed tillig closed 8 years ago
Can you put together a small reproduction showing the issue and post it somewhere? I've never seen the behavior you describe and we can't troubleshoot it just based on the description.
Also, I'm going to move this to the Autofac.WebApi repo since we track issues for individual integrations in the respective repositories.
Ok there is 4 parts in my code :
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
builder.RegisterModule(new DefaultTestModule());
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
app.UseWebApi(config);
builder.Register(c => (ClaimsIdentity) HttpContext.Current.GetOwinContext().Authentication.User.Identity)
.As<ClaimsIdentity>()
.InstancePerRequest();
builder.Register(c => new HttpContextWrapper(HttpContext.Current))
.As<HttpContextBase>()
.InstancePerRequest();
var httpContext = c.Resolve<HttpContextBase>();
if (httpContext == null)
{
return null;
}
var context = c.Resolve<TestContext>();
var tenantProvider = c.Resolve<ITenantProvider>();
var tenant = tenantProvider.GetTenant(httpContext);
var identity = (ClaimsIdentity)context.User.Identity;
List<Claim> claims = identity.Claims.ToList();
var claim = claims.Where(c => c.Type == "TenantId").FirstOrDefault();
if (claim == null)
{
throw new WrongTokenException("Cannot resolve tenantid");
}
return Guid.Parse(claim.Value);
In the utilisation, identity is always empty (name, claims, etc...) but when I go in my ApiController...I can do that
if (string.IsNullOrWhiteSpace(_UserId))
{
var identity = (ClaimsIdentity)User.Identity;
List<Claim> claims = identity.Claims.ToList();
var claim = claims.Where(c => c.Type == "UserId").FirstOrDefault();
if (claim == null)
{
throw new WrongTokenException("Cannot resolve userid");
}
_UserId = claim.Value;
}
return _UserId;
The identity is correct.
The reason I need a reproduction and not just some snippets of code is that I need to see when in the app things are happening. For example, your authentication process - the thing that sets the identity on the HttpContext
- may be running after your "utilisation" section, which would explain why it's null: it hasn't been set yet.
But I can't tell from just snippets. I need a full working repro.
Sorry, it would be really hard to make a reproduction from my code without showing important stuff regarding my company. Just one thing got my attention, when you said : " For example, your authentication process - the thing that sets the identity on the HttpContext - may be running after your "utilisation" section, which would explain why it's null: it hasn't been set yet.". The thing is I have nothing in my code which set the Identity, I think Owin takes care of it. I will try to check that and if I don't resolve that, I will try to give you a real reproduction.
AFAIK The part of Owin that sets the identity occurs after the constructor for the controller fires. User info is not available until the Controller method is hit.
AFAIK The part of Owin that sets the identity occurs after the constructor for the controller fires. User info is not available until the Controller method is hit.
Has anybody been able to find a way to get the current user while autofac is creating the api controller? I've tried to get to the RequestContext, but Identity is always just an empty generic claim principle with a null auth type, and not our Bearer authed principle. Without being able to do this, I can't inject our db context into api controllers because it needs the user/tenant info to get a connection string.
It's strange that when injecting the EF db context into MVC controllers using WS-Fed owin auth the user is in HttpContext.Current.User but not when creating webapi2 controllers.
@PilotBob have you found a workaround to inject db context with the right user identity?
@PilotBob have you found a workaround to inject db context with the right user identity?
No. We ended up not using constructor injection in our api controllers. We use the Containter.Resolve method in the action.
I think this is because our API auth is passive. I expect this would work if it was active. But since our api is shared by our MVC controllers where ws-fed is the active auth that's not an option. I think the only way to do it would be to make the api a separate app. But, I haven't tried to, or wanted to go down that road.
From @toben on November 9, 2015 14:34
It's weird, when I am in my ApiController, HttpContext.Current.User.Identity is good. IsAuthenticated is true, name is the username, etc... But, before that, when I am in a resolution of an "InstancePerRequest" injection, HttpContext.Current.User.Identity is weird and all fields are null or empty...
This is the code which inject HttpContext.Current in other injections. How that can be possible ?
Copied from original issue: autofac/Autofac#692