A simple injector gets the current principle in WebAPI using OWIN

In any case, in order to get access to the current main person even before the request arrives at the controller using Simple Injector? I use OWIN and Asp.net identifiers.

I have a DbContext that I insert into my controllers, but this context will get a connection string based on the authenticated user. This is what I still have

container.RegisterWebApiRequest<TenantDbContext>();
container.RegisterWebApiRequest<ITenantConnectionStringProvider>(() => new TenantConnectionStringProvider(container));

Then in my TenantConnectionStringProvider I have this,

var request = container.GetCurrentHttpRequestMessage();
var principal = request.GetRequestContext().Principal as ClaimsPrincipal;

But the principal has no complaints. I realized that claims are only available after the controller has been created. Does this mean that it is simply impossible, because this step precedes the creation of the controller?

Edit: This is basically what the rest of the code does:

WebApi Controller

    public CampaignsController(TenantDbContext context, ILog log)
    {
        this.campaignService = campaignService;
        this.log = log;
    }

( DbContext EF):

    public TenantDbContext(ITenantConnectionStringProvider provider)
        : base(provider.GetConnectionString())
    {
    }

, . OWIN, . , , , TenantConnectionStringProvider, HttpRequestMessage.

        app.Use(async (context, next) =>
        {
            using (container.BeginExecutionContextScope())
            {
                CallContext.LogicalSetData("Claims", context.Authentication.User.Claims);
                var request = (OwinRequest)context.Request;
                await next();
            }
        });

TenantConnectionStringProvider ,

    public string GetConnectionString()
    {
        var context = (IEnumerable<Claim>)CallContext.LogicalGetData("Claims");
        return "test";//get claim from context to get the connection string
    }
+4
2

Func<ClaimsPrincipal> (factory) TenantConnectionStringProvider:

public class TenantConnectionStringProvider : ITenantConnectionStringProvider
{
    private readonly Func<ClaimsPrincipal> _claimsPrincipalFactory;
    public TenantConnectionStringProvider(Func<ClaimsPrincipal> claimsPrincipalFactory)
    {
        _claimsPrincipalFactory = claimsPrincipalFactory;            
    }

    public void TestMethod()
    {
        // Access the current principal
        var principal = _claimsPrincipalFactory();
    }
}

( ...):

// Register your types, for instance using the scoped lifestyle:
container.RegisterSingleton<Func<ClaimsPrincipal>>(() =>
{
    // Not sure of which one to use.
    //return (ClaimsPrincipal)HttpContext.Current.User;
    //return (ClaimsPrincipal)Thread.CurrentPrincipal;
    return (ClaimsPrincipal)Context.User;
});
container.RegisterWebApiRequest<ITenantConnectionStringProvider, TenantConnectionStringProvider>();
+5

, , ?

, . simple-injector , Lazy<> :

var request = container.GetCurrentHttpRequestMessage();
var principal = new Lazy<ClaimsPrincipal>(() => 
  {
    return request.GetRequestContext().Principal as ClaimsPrincipal;
  });

, ( , - , ), principal.Value, ClaimsPrincipal. , , , , . , dbcontext ( ), .

+3

Source: https://habr.com/ru/post/1626935/


All Articles