Pregunta

He escrito una aplicación Silverlight 2 la comunicación con un servicio de WCF (BasicHttpBinding).El sitio de alojamiento de los contenidos de Silverlight está protegida con una ASP.NET Proveedor de Pertenencia.Puedo acceder al usuario actual utilizando HttpContext.Actual.Usuario.De la identidad.Nombre de mi servicio WCF, y me he convertido en AspNetCompatibilityRequirementsMode.

Ahora quiero escribir una aplicación de Windows con el mismo servicio web.Para gestionar la autenticación he habilitado el El servicio de autenticación de, y podemos llamar "inicio de sesión" para autenticar mi usuario...Okey, todo bien...Pero, ¿cómo diablos hago para conseguir que la cookie de autenticación configurado en mi otro servicio de cliente?!

Ambos servicios están alojados en el mismo dominio

  • MyDataService.svc <- el trato con mis datos
  • AuthenticationService.svc <- el que la aplicación de windows tiene que llamar a autenticar.

No quiero crear un nuevo servicio para el cliente de windows, o utilizar otro enlace...

La Aplicación de Cliente de Servicios es otra alternativa, pero en todos los ejemplos que se limita a mostrar cómo conseguir que el usuario, roles y su perfil...Pero una vez que estamos autenticados mediante la Aplicación de Cliente de Servicios debe haber una manera de conseguir que la cookie de autenticación que está conectado al servicio de clientes a la hora de volver a llamar al mismo servidor.

De acuerdo a las aportaciones de los colegas de la solución es la adición de un wsHttpBinding de punto final, pero tengo la esperanza de poder conseguir alrededor de eso...

¿Fue útil?

Solución

Finalmente encontré una manera de hacer este trabajo.Para la autenticación estoy usando el "WCF Servicio de Autenticación".A la hora de autenticar el servicio intentará establecer una cookie de autenticación.Necesito conseguir esta cookie de la respuesta, y agregarlo a cualquier otra solicitud hecha a otros servicios web en la misma máquina.El código para hacer que se parece a esto:

var authService = new AuthService.AuthenticationServiceClient();
var diveService = new DiveLogService.DiveLogServiceClient();

string cookieHeader = "";
using (OperationContextScope scope = new OperationContextScope(authService.InnerChannel))
{
    HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestProperty;
    bool isGood = authService.Login("jonas", "jonas", string.Empty, true);
    MessageProperties properties = OperationContext.Current.IncomingMessageProperties;
    HttpResponseMessageProperty responseProperty = (HttpResponseMessageProperty)properties[HttpResponseMessageProperty.Name];
    cookieHeader = responseProperty.Headers[HttpResponseHeader.SetCookie];                
}

using (OperationContextScope scope = new OperationContextScope(diveService.InnerChannel))
{
    HttpRequestMessageProperty httpRequest = new HttpRequestMessageProperty();
    OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequest);
    httpRequest.Headers.Add(HttpRequestHeader.Cookie, cookieHeader);
    var res = diveService.GetDives();
}      

Como puedes ver tengo dos clientes del servicio, uno para el servicio de autenticación, y una para el servicio realmente voy a utilizar.El primer bloque se llame el método de inicio de Sesión, y utilizar la cookie de autenticación de la respuesta.El segundo bloque va a agregar el encabezado de la solicitud antes de llamar a la "GetDives" método de servicio.

No estoy contento con este código a todos, y creo que una mejor alternativa podría ser la utilización de la Web "de Referencia" en lugar de "Servicio de Referencia" y el uso de la .NET 2.0 de la pila en su lugar.

Otros consejos

Web de servicios, tales como los creados por la WCF, a menudo son los más utilizados en un "apátrida" camino, de modo que cada llamada a un servicio Web comienza de nuevo.Esto simplifica el código del servidor, ya que no es necesario tener una "sesión", que recuerda el estado del cliente.También simplifica el código de cliente, ya que no es necesario mantener los boletos, cookies, u otros geegaws que asumir algo sobre el estado del servidor.

La creación de dos servicios en la forma que se describe introduce statefulness.El cliente es "autentica" o "no autenticado", y el MyDataService.svc tiene que averiguar.

Como sucede, he encontrado WCF para funcionar bien cuando el proveedor de pertenencia se utiliza para autenticar cada llame a un servicio.Así, en el ejemplo dado, te gustaría agregar el proveedor de pertenencia de autenticación gubbins a la configuración del servicio para MyDataService, y no tienen un servicio de autenticación en todo.

Para más detalles, vea el artículo de MSDN aquí.

[Lo que es muy atractivo para mí, como soy vago, es que esto es completamente declarativo.Yo simplemente esparcir el derecho de configuración de las entradas para mi MembershipProvider en la aplicación.config de la aplicación y de!bingo!todas las llamadas a cada contrato en el servicio de autenticación.]

Es justo señalar que esta no va a ser particularmente rápido.Si está utilizando SQL Server para su autenticación de base de datos que tendrá al menos una, quizás dos llamadas a procedimientos almacenados por el servicio de llamada.En muchos casos (especialmente para los enlaces HTTP) la sobrecarga de la llamada de servicio será mayor;si no, considere la posibilidad de lanzar su propia aplicación de un proveedor de pertenencia que se almacena en caché las solicitudes de autenticación.

Una cosa que esta no dar es la capacidad de proporcionar un "inicio de sesión" en la capacidad.Por eso, puede proveer un (autenticada!) contrato de servicio que no hace nada (aparte de criar a un fallo si la autenticación falla), o puede utilizar el proveedor de pertenencia servicio como se describe en el original se hace referencia en el artículo.

En el cliente modifique su <binding> etiqueta de servicio (dentro de <system.serviceModel>) para incluir:allowCookies="true"

La aplicación ahora debe conservar la cookie y el uso de la misma.Tenga en cuenta que IsLoggedIn ahora devuelve true después de iniciar sesión en -- devuelve false si no estás permitiendo que las cookies.

Es posible ocultar gran parte de la extra de código detrás de un mensaje personalizado inspector y la conducta de modo que usted no necesita tomar el cuidado de juguetear con el OperationContextScope a ti mismo.

Voy a tratar de burlarse de algo más tarde y se la enviaremos.

--larsw

Usted debe echar un vistazo a la CookieContainer objeto en System.Net.Este objeto permite a un no-cliente de explorador para aferrarse a las cookies.Esto es lo que mi equipo utilizado la última vez que nos encontramos con ese problema.

Aquí está un breve artículo sobre cómo ir sobre su uso.No puede ser mejor que hay, pero esto debe empezar.

Fuimos los apátridas ruta para nuestro actual conjunto de servicios WCF y Silverlight 2 de la aplicación.Es posible obtener el 2 de Silverlight para trabajar con los servicios vinculados con TransportWithMessageCredential de seguridad, aunque tiene algunos personalizada código de seguridad en el Silverlight lado.El resultado de todo esto es que cualquier aplicación puede acceder a los servicios simplemente poniendo el nombre de Usuario y la Contraseña en los encabezados de los mensajes.Esto se puede hacer una vez en una costumbre IRequestChannel aplicación con el fin de que los desarrolladores no necesitan preocuparse acerca de la configuración de los valores por sí solos.A pesar de WCF tiene una manera fácil para los desarrolladores para hacer esto que yo creo que es serviceProxy.De seguridad.Nombre de usuario y serviceProxy.De seguridad.Contraseña o algo igual de sencillo.

Esto lo escribí hace un tiempo cuando yo estaba usando los Servicios de Aplicación Cliente para autenticar contra de los servicios web.Se utiliza un mensaje de inspector para insertar el encabezado de cookie.Hay un archivo de word con la documentación y un proyecto de demostración.Aunque no es exactamente lo que están haciendo, su muy cerca.Se puede descargar desde aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top