Para la autenticación básica que han puesto en marcha una costumbre HttpMessageHandler
basado en el ejemplo mostrado en la respuesta de Darin Dimitrov aquí: https://stackoverflow.com/a/11536349/270591¿Cómo puedo establecer de forma segura el principal del usuario en un WebAPI HttpMessageHandler personalizado?
El código crea una instancia principal
de tipo GenericPrincipal
con el nombre y los roles de usuario y luego establece este principio al director actual de la rosca:
Thread.CurrentPrincipal = principal;
Más tarde, en un método ApiController
el principal puede ser leído mediante el acceso a los controladores User
propiedad:
public class ValuesController : ApiController
{
public void Post(TestModel model)
{
var user = User; // this should be the principal set in the handler
//...
}
}
Esto pareció funcionar bien hasta que he añadido recientemente un encargo MediaTypeFormatter
que utiliza la biblioteca Task
así:
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;
}
(tengo este enfoque para comenzar una tarea con Task.Factory.StartNew
en ReadFromStreamAsync
de un código de ejemplo. ¿Es incorrecto y tal vez la única razón para el problema?)
Ahora, "a veces" - y para mí parece ser aleatorio - el principal User
en el método del controlador ya no es el principal que he establecido el MessageHandler, es decir, el nombre de usuario, el indicador Authenticated
y todos los roles se han perdido. La razón parece ser que el MediaTypeFormatter personalizado provoca un cambio del hilo entre MessageHandler y el método del controlador. Lo he confirmado comparando los valores de Thread.CurrentThread.ManagedThreadId
en MessageHandler y en el método del controlador. "A veces" son diferentes y luego el director está "perdido".
He mirado ahora para alternativa a la configuración Thread.CurrentPrincipal
para transferir de alguna manera el director de seguridad de la MessageHandler personalizado al método de controlador y en this blog post propiedades de la solicitud se utilizan:
request.Properties.Add(HttpPropertyKeys.UserPrincipalKey,
new GenericPrincipal(identity, new string[0]));
quería probar eso, pero parece que la clase HttpPropertyKeys
(que está en el espacio de nombres System.Web.Http.Hosting
) ya no tiene una propiedad UserPrincipalKey
en las versiones recientes de WebApi (versión de lanzamiento y versión final de la semana pasada también).
Mi pregunta es: ¿Cómo puedo cambiar el último fragmento de código anterior para que funcione con la versión actual de WebAPI? O en general: ¿cómo puedo configurar el principal del usuario en un MessageHandler personalizado y acceder de manera confiable en un método de controlador?
Editar
Se menciona here que "... HttpPropertyKeys.UserPrincipalKey
resuelve a “MS_UserPrincipal”
", por lo que trató de usar:
request.Properties.Add("MS_UserPrincipal",
new GenericPrincipal(identity, new string[0]));
Pero no funciona como esperaba: La ApiController.User
propiedad no contiene el principal agregado a la colección Properties
anterior.
Sugiero mirar este https://github.com/thinktecture/Thinktecture.IdentityModel.45 –