У меня есть фильтр авторизации, который проверяет токен. Фильтр реализован как IAuthorizationFilter с классом атрибута reparate, чтобы включить внедрение конструктора. Это отлично работает. Когда токен проверяется, он сохраняется в 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();
Фильтр:
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();
}