c# - 简单注入(inject)器使用 OWIN 在 WebAPI 中获取当前主体

标签 c# asp.net asp.net-web-api owin simple-injector

有没有办法在请求到达 Controller 之前使用简单注入(inject)器访问当前主体?我正在使用 OWIN 和 Asp.net 身份。

我有一个 DbContext 注入(inject)到我的 Controller 中,但是这个上下文将根据经过身份验证的用户获取它的连接字符串。这是我目前所拥有的,

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

然后在我的 TenantConnectionStringProvider 中我有这个,

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

但是校长没有任何主张。我意识到声明仅在创建 Controller 后可用。这是否意味着这是不可能的,因为这一步是在创建 Controller 之前进行的?

编辑: 这基本上就是其余代码的作用:

WebAPI Controller

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

租户上下文(仅继承自 EF 的 DbContext):

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

经过一番折腾后,我能够做到这一点,但感觉非常 hacky.. 我添加了一个在身份验证后发生的 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
    }

最佳答案

您可以注册一个Func<ClaimsPrincipal> (工厂)并将其注入(inject)您的 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>();

关于c# - 简单注入(inject)器使用 OWIN 在 WebAPI 中获取当前主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35142353/

相关文章:

c# - 如何在 Visual Studio 中为项目引用设置 "Specific Version"属性

c# - 如何检查 HttpContext.Current.Response 是否有现有的 Header?

c# - MaxLength + Asp.net Web API - 错误

.net - 使用自定义 DirectRouteProvider 手动创建路由别名会导致 "Multiple actions were found that match the request"错误

c# - 在 ADO.NET 中处理 "using"语句

.NET 4.5 HttpClient PUT 或 POST over SSL 总是失败

c# - HttpWebRequest 使用 cookie 重定向

c# - ClientBase<TChannel> 和 ChannelFactory<TChannel> 的代码生成?

Linux 网络服务器上的 ASP.NET

javascript - onkeypress 不适用于 asp.net webform 中的文本框