Aplicación de la Tienda Windows con autenticación y suplantación empresarial
Version corta: ¿Por qué cuando me hago pasar por una solicitud web realizada por la aplicación de la Tienda Windows, obtengo el objeto WindowsIdentity con el nombre de usuario correcto, pero su propiedad IsAuthenticated devuelve False? Hacer la misma solicitud desde un navegador (incluido Metro IE10) le da a IsAuthenticated == true.
Versión larga:
Estoy creando un prototipo de una solución empresarial interna, que consiste en el servicio WCF y la aplicación WinJS. El servicio WCF se basa en el enlace webHttpBinding (es decir, solicitudes GET / POST simples).
Ciertas acciones deben procesarse en nombre de un usuario que realiza una solicitud, por lo tanto, el servicio está configurado para hacerse pasar por sus llamadores. Aquí está la configuración de muestra:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="CustomizedWebBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="Web">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="WcfService">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="CustomizedWebBinding" contract="IWcfService" behaviorConfiguration="Web">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8787/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
... y el código:
public class WcfService : IWcfService
{
[OperationBehavior(Impersonation=ImpersonationOption.Required)]
public UserInfo GetUserInfo()
{
UserInfo ui = new UserInfo();
WindowsIdentity identity = ServiceSecurityContext.Current.WindowsIdentity;
ui.UserName = identity.Name;
ui.IsAuthenticated = identity.IsAuthenticated;
ui.ImpersonationLevel = identity.ImpersonationLevel.ToString();
ui.IsAnonymous = identity.IsAnonymous;
ui.IsGuest = identity.IsGuest;
ui.IsSystem = identity.IsSystem;
ui.AuthenticationType = identity.AuthenticationType;
return ui;
}
}
Por lo tanto, esta operación simplemente recopila información sobre la persona que llama y la devuelve en una cadena json.
Moviéndose al cliente. Para habilitar la autenticación automática, verifiqué "Autenticación de empresa", "Internet (cliente)" y "Redes privadas" en el archivo de manifiesto de la aplicación de la Tienda Windows.
Desde la aplicación de la Tienda Windows, envío una solicitud utilizando la función WinJS.xhr:
var options = {
url: "http://localhost:8787/getuserinfo"
};
WinJS.xhr(options).then(function (xhrResponse) {
var userInfoBlock = document.getElementById("userInfoBlock");
var data = JSON.parse(xhrResponse.response);
userInfoBlock.innerHTML += "<ul>"
for (var p in data) {
if (data.hasOwnProperty(p)) {
userInfoBlock.innerHTML += "<li>" + p + ": " + data[p] + "</li>";
}
}
userInfoBlock.innerHTML += "</ul>";
});
Ahora, cuando ejecuto la aplicación de la Tienda Windows y envía una solicitud, la respuesta que recibo es:
AuthenticationType: "NTLM"
ImpersonationLevel: "Impersonation"
IsAnonymous: false
IsAuthenticated: false
IsGuest: false
IsSystem: false
UserName: "TESTBOX\dev"
Si envío una solicitud utilizando la barra de direcciones del navegador, obtengo la misma respuesta, con la única diferencia de que "IsAuthenticated: true".
También me di cuenta de que si deshabilito la "Autenticación de la empresa", aparece el selector de credenciales y, después de proporcionar las credenciales correctas, obtengo "IsAuthenticated: true".
¿Me estoy perdiendo algo o estoy esperando demasiado de la capacidad de autenticación empresarial?