У меня есть проект Web API 2, и мы используем базовую авторизацию. Клиент отправляет имя пользователя: пароль в заголовке авторизации — мы извлекаем его и подключаемся к серверу LDAP для
- проверить пользователя
- подтвердите свой пароль, а затем
- получить значение атрибута из своего ответа LDAP и передать его в IPrincipal запроса.
Проблема в том, что когда я обращаюсь к IPrincipal в контроллере через System.Web.Http.ApiController.User.Identity.Name, я вижу, что переданное значение не всегда правильно!
Пример: либо в обработчике сообщений, либо в фильтре я установил IPrincipal следующим образом:
public class BasicAuthenticationAttribute : Attribute, IAuthenticationFilter
{
...other code...
private IPrincipal ReturnPrincipal(string UserID, List<string> roles)
{
roles.Add("SomeRole");
// UserID = 7144 or 8899 (load testing)
var identity = new GenericIdentity(UserID, "Basic");
var principal = new GenericPrincipal(identity, roles.ToArray());
return principal;
}
}
Редактировать: вот как мы устанавливаем принцип в фильтре:
var principal = await AuthenticateAsync(UserID, password, cancellationToken);
if (principal == null)
{
// Authentication was attempted but failed. Set ErrorResult to indicate an error.
context.ErrorResult = new AuthenticationFailureResult("Invalid username or password", request);
}
else
{
// Authentication was attempted and succeeded. Set Principal to the authenticated user.
context.Principal = principal;
}
Позже в жизненном цикле запроса в контроллере я пытаюсь получить доступ к этому значению следующим образом:
protected bool IsAuthorized(string UserID)
{
return User.Identity.Name == UserID;
}
Итак, здесь происходит следующее: я получаю User.Identity.Name от ApiController.User.Identity.Name в разделе нагрузочное тестирование, я отправить 2 параллельных запроса с нитями в ОДНО ВРЕМЯ - когда я это делаю, объект запроса показывает правильный идентификатор в URL-адресе, однако IPrincipal, установленный в фильтре, НЕ является правильным. Это фиксированный тест с ожидаемыми результатами, поэтому этого никогда не должно происходить. Если это поразить звонки, проблема не возникает! Если звонки отправляются одновременно, проблема возникает в 100% случаев.
Вот как я вызываю службу:
var task1 = Task.Run(() => CallServerInParallel(requests2, api));
var task2 = Task.Run(() => CallServerInParallel2(requests2, api));
Task.WaitAll(task1, task2);
...
private static void CallServerInParallel2(List<int> requests2, string api)
{
Parallel.ForEach(requests2, new ParallelOptions() { MaxDegreeOfParallelism = 2 }, async p =>
{
var client = new RemoteClient(api);
client.AddAuthHeader("d2JsMTE4NTgzOUBbdGVhY2NlcHQuY29tOnRlc3QxMjM0");
var response = await client.Get<dynamic>("CustomerSite/5537");
});
}
private static void CallServerInParallel2(List<int> requests2, string api)
{
Parallel.ForEach(requests2, new ParallelOptions() { MaxDegreeOfParallelism = 2 }, async p =>
{
var client = new RemoteClient(api);
client.AddAuthHeader("d2JsMTE4NTgzOUBkdGVhY1NlcHQuY29tOnRlc3QxMjM0");
var response = await client.Get<dynamic>("CustomerSite/5538");
});
}
Как я могу получить доступ к правильному IPrincipal.User.Identity.Name для запроса?
ReturnPrincipal
вызывается? Где вы на самом деле устанавливаете принципала в контексте? - person   schedule 03.02.2016