Como posso definir com segurança o usuário principal em um WebAPI HttpMessageHandler personalizado?
Para autenticação básica, implementei umHttpMessageHandler
com base no exemplo mostrado na resposta de Darin Dimitrov aqui:https://stackoverflow.com/a/11536349/270591
O código cria uma instânciaprincipal
do tipoGenericPrincipal
com nome de usuário e funções e, em seguida, define esse principal para o principal atual do segmento:
Thread.CurrentPrincipal = principal;
Mais tarde em umApiController
método o principal pode ser lido, acessando os controladoresUser
propriedade:
public class ValuesController : ApiController
{
public void Post(TestModel model)
{
var user = User; // this should be the principal set in the handler
//...
}
}
Isso pareceu funcionar bem até que eu adicionei recentemente um costumeMediaTypeFormatter
que usa oTask
biblioteca como assim:
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream,
HttpContent content, IFormatterLogger formatterLogger)
{
var task = Task.Factory.StartNew(() =>
{
// some formatting happens and finally a TestModel is returned,
// simulated here by just an empty model
return (object)new TestModel();
});
return task;
}
(Eu tenho essa abordagem para iniciar uma tarefa comTask.Factory.StartNew
emReadFromStreamAsync
de algum código de amostra. Está errado e talvez a única razão para o problema?)
Agora, "às vezes" - e para mim parece ser aleatório - oUser
principal no método do controlador não é mais o principal que eu configurei no MessageHandler, ou seja, nome de usuário,Authenticated
bandeira e papéis estão todos perdidos. O motivo parece ser que o MediaTypeFormatter personalizado causa uma alteração do encadeamento entre o MessageHandler e o método do controlador. Eu confirmei isso comparando os valores deThread.CurrentThread.ManagedThreadId
no MessageHandler e no método do controlador. "Às vezes" eles são diferentes e, em seguida, o principal é "perdido".
Eu olhei agora para uma alternativa para definirThread.CurrentPrincipal
para de alguma forma transferir o principal com segurança do MessageHandler personalizado para o método do controlador e emeste post de blog propriedades de solicitação são usadas:
request.Properties.Add(HttpPropertyKeys.UserPrincipalKey,
new GenericPrincipal(identity, new string[0]));
Eu queria testar isso, mas parece que oHttpPropertyKeys
class (que está no namespaceSystem.Web.Http.Hosting
) não temUserPrincipalKey
propriedade mais nas versões recentes do WebApi (release candidate e release final da semana passada também).
Minha pergunta é: Como posso alterar o último snippet de código acima para que funcione com a versão atual do WebAPI? Ou geralmente: Como posso definir o usuário principal em um MessageHandler personalizado e acessá-lo de forma confiável em um método do controlador?
Editar
É mencionadoAqui naquela "HttpPropertyKeys.UserPrincipalKey
... resolve“MS_UserPrincipal”
", então eu tentei usar:
request.Properties.Add("MS_UserPrincipal",
new GenericPrincipal(identity, new string[0]));
Mas não funciona como eu esperava:ApiController.User
propriedade não contém o principal adicionado aoProperties
coleção acima.