C# Ninject Asp.Net WebApi授权筛选器执行顺序
我有一个检查令牌的授权筛选器。该过滤器被实现为IAuthorizationFilter,带有一个reparate Atribute类,以便启用构造函数注入。这个很好用。 检查令牌后,它将存储在Thread.CurrentPrincipal中 问题是当我在具有该属性的控制器中使用它时。控制器还注入了一个类,其中必须知道当前用户。它需要为属于用户组的数据库使用正确的连接字符串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
[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就是这样。我将研究在控制器中使用工厂,或者可能使用。非常感谢。