C# Ninject Asp.Net WebApi授权筛选器执行顺序

C# Ninject Asp.Net WebApi授权筛选器执行顺序,c#,asp.net-web-api,ninject,C#,Asp.net Web Api,Ninject,我有一个检查令牌的授权筛选器。该过滤器被实现为IAuthorizationFilter,带有一个reparate Atribute类,以便启用构造函数注入。这个很好用。 检查令牌后,它将存储在Thread.CurrentPrincipal中 问题是当我在具有该属性的控制器中使用它时。控制器还注入了一个类,其中必须知道当前用户。它需要为属于用户组的数据库使用正确的连接字符串 [TestAuthorizeToken] public class TestController : BaseApiCont

我有一个检查令牌的授权筛选器。该过滤器被实现为IAuthorizationFilter,带有一个reparate Atribute类,以便启用构造函数注入。这个很好用。 检查令牌后,它将存储在Thread.CurrentPrincipal中

问题是当我在具有该属性的控制器中使用它时。控制器还注入了一个类,其中必须知道当前用户。它需要为属于用户组的数据库使用正确的连接字符串

[TestAuthorizeToken]
public class TestController : BaseApiController
{
    IUserDetails user;

    public TestController(IUserDetails _user)
    {
        this.user = _user;
    }

    [HttpGet]
    [Route("GetClientCode")]
    public string GetClientCode()
    {
        return user.ClientCode;
    }
}
我假设过滤器代码总是首先运行,因此会检查标识并将其存储在线程中

但是,出乎意料的是,UserDetails类是在过滤器代码运行之前实例化的。因此,我无法在UserDetails实例化中使用标识

有没有办法确保在这种情况下首先运行授权码? 还是我忽略了什么?

相关绑定:

kernel.BindHttpFilter<TestAuthorizeTokenFilter>(System.Web.Http.Filters.FilterScope.Controller)
    .WhenControllerHas<TestAuthorizeTokenAttribute>();

kernel.Bind<IUserDetails>().To<UserDetails>();

kernel.Bind<IMasterUserRepoFactory>().ToFactory();
kernel.BindHttpFilter(System.Web.Http.Filters.FilterScope.Controller)
.WhenControllerHas();
kernel.Bind().To();
kernel.Bind().ToFactory();
过滤器:

public class TestAuthorizeTokenAttribute : System.Web.Http.Filters.AuthorizationFilterAttribute
{
}

public class TestAuthorizeTokenFilter : System.Web.Http.Filters.IAuthorizationFilter
{
    private IMasterUserRepo masterUserRepo;
    private IMasterUserRepoFactory masterUserRepoFactory;

    public TestAuthorizeTokenFilter(IMasterUserRepoFactory masterUserRepoFactory)
    {
        this.masterUserRepoFactory = masterUserRepoFactory;
    }

    public bool AllowMultiple
    {
        get
        {
            return false;
        }
    }

    public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
    {
        if (Thread.CurrentPrincipal.Identity.IsAuthenticated)
        {
            return continuation();  
        }

        masterUserRepo = this.masterUserRepoFactory.Create();

        AuthenticationHeaderValue authHeader = actionContext.Request.Headers.Authorization;

        if (authHeader != null)
        {
            // Simplified
            string token = authHeader.Parameter;
            var masterUser = masterUserRepo.GetItemByToken(token);
            // ...
            var identity = new GenericIdentity(token);
            var principal = new GenericPrincipal(identity, null);
            Thread.CurrentPrincipal = principal;

            return continuation();  
        }

        return Task.FromResult(new HttpResponseMessage(HttpStatusCode.Unauthorized));
    }
}

public interface IMasterUserRepoFactory
{
    IMasterUserRepo Create();
}
公共类TestAuthorizeTokenAttribute:System.Web.Http.Filters.AuthorizationFilterAttribute
{
}
公共类TestAuthorizeTokenFilter:System.Web.Http.Filters.IAAuthorizationFilter
{
私有IMasterUserRepo masterUserRepo;
私有IMasterUserRepoFactory主用户RepoFactory;
公共TestAuthorizeTokenFilter(IMasterUserRepoFactory masterUserRepoFactory)
{
this.masterUserRepoFactory=masterUserRepoFactory;
}
公共布尔允许多个
{
得到
{
返回false;
}
}
公共任务ExecuteAuthorizationFilterAsync(HttpActionContext actionContext、CancellationToken CancellationToken、Func continuation)
{
if(Thread.CurrentPrincipal.Identity.IsAuthenticated)
{
返回continuation();
}
masterUserRepo=this.masterUserRepoFactory.Create();
AuthenticationHeaderValue authHeader=actionContext.Request.Headers.Authorization;
if(authHeader!=null)
{
//简化
字符串标记=authHeader.Parameter;
var masterUser=masterUserRepo.GetItemByToken(令牌);
// ...
var标识=新的GenericEntity(令牌);
var principal=新的GenericPrincipal(标识,null);
Thread.CurrentPrincipal=主体;
返回continuation();
}
返回Task.FromResult(新的HttpResponseMessage(HttpStatusCode.Unauthorized));
}
}
公共接口IMasterUserRepoFactory
{
IMasterUserRepo Create();
}

可能您没有在正确的位置执行身份验证。这可能有助于@jbl,谢谢。你能再解释一下吗?我是否使用了错误的方法?您可能会将IUserDetails工厂注入控制器。因此,UserDetails只能在您的操作中得到解决。至于身份验证,您可以依赖专用过滤器或使用owin@jbl就是这样。我将研究在控制器中使用工厂,或者可能使用。非常感谢。可能您没有在正确的位置执行身份验证。这可能有助于@jbl,谢谢。你能再解释一下吗?我是否使用了错误的方法?您可能会将IUserDetails工厂注入控制器。因此,UserDetails只能在您的操作中得到解决。至于身份验证,您可以依赖专用过滤器或使用owin@jbl就是这样。我将研究在控制器中使用工厂,或者可能使用。非常感谢。