Twitter Facebook RSS Feed

martes, 23 de marzo de 2010 a las 21:38hs por Gustavo Cantero (The Wolf)

Hace unos meses Darío escribió un artículo donde explica cómo utilizar los servicios de autenticación y roles que posee ASP.NET en nuestras páginas (https://www.programandoamedianoche.com/2009/10/autenticacion-por-formularios-en-asp-net), tanto desde el servidor como utilizando AJAX (https://www.programandoamedianoche.com/2009/10/autenticacion-por-formularios-en-asp-net/3). Para complementarlo se me ocurrió escribir un artículo que explique cómo utilizar este servicio de autenticación desde Silverlight.
Para comenzar vamos a crear un proyecto Silverlight en nuestro Visual Studio, junto con su proyecto web de prueba (el cual va a exponer los servicios de autenticación).
Para utilizar estos servicios desde Silverlight (o desde cualquier aplicación externa) necesitamos publicarlos a través de WCF (Windows Communication Foundation). Para esto primero necesitamos configurar el servicio en el web.config, en la sección “Services”, apuntando a la clase “System.Web.ApplicationServices.AuthenticationService”. Cabe mencionar que necesitamos establecer la compatibilidad del servicio con ASP.NET, ya que sólo es soportado con http.

<system.serviceModel>
  <services>
    <service name="System.Web.ApplicationServices.AuthenticationService"
             behaviorConfiguration="AuthenticationServiceTypeBehaviors">
      <endpoint contract="System.Web.ApplicationServices.AuthenticationService"
                binding="basicHttpBinding" bindingConfiguration="http"
                bindingNamespace="http://asp.net/ApplicationServices/v200"/>
    </service>
  </services>
  <bindings>
    <basicHttpBinding>
      <!--En producción es aconsejable utilizar https-->
      <binding name="http">
        <security mode="None"/>
      </binding>
    </basicHttpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
      <behavior name="AuthenticationServiceTypeBehaviors">
        <serviceMetadata httpGetEnabled="true"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>

Luego necesitamos habilitar los servicios web de autenticación a través de las siguientes líneas:

<system.web.extensions>
  <scripting>
    <webServices>
      <authenticationService enabled="true" requireSSL="false"/>
    </webServices>
  </scripting>
</system.web.extensions>

Y el último cambio que necesitamos hacer al web.config es para establecer la autenticación en “Forms”, utilizando:

<authentication mode="Forms" />

Bien, ahora que ya tenemos configurada nuestra aplicación debemos crear el archivo que exponga el servicio de autenticación. Para esto simplemente tenemos que agregar un archivo de tipo texto (“Text File”), para que el Visual Studio no le cree el code behind, y llamarlo, por ejempo, Authentication.svc. En este archivo vamos a agregar solamente una línea que apunte a la clase de ASP.NET que implementa el servicio de autenticación:

<%@ ServiceHost Service="System.Web.ApplicationServices.AuthenticationService" %>

Ahora ya tenemos una aplicación web que utiliza los servicios de autenticación de ASP.NET y los expone a través de servicios web, por lo tanto ahora, en el proyecto Silverlight, vamos a agregar la referencia al servicio creado en el paso anterior. Para esto pulsamos el botón derecho del mouse sobre el proyecto y elegimos la opción “Add Service Reference”, luego en el diálogo que se muestra pulsamos en “Discover” para que busque los servicios publicados en nuestra solución, elegimos “Authentication.svc” de la lista, cambiamos el namespace donde queremos que cree las clases (en nuestro ejemplo lo dejamos como está: “ServiceReference1”), y pulsamos “OK”. Esto nos creará las clases proxy para que nuestra aplicación Silverlight se conecte y utilice los servicios de autenticación expuestos por nuestra aplicación web.

Agregar servicio web de Autenticación

La clase cliente que creamos, llamada en nuestro ejemplo “ServiceReference1.AuthenticationServiceClient”, tiene tres métodos importantes: LoginAsync, LogoutAsync e IsLoggedInAsync. Nótese que todos los métodos de los servicios web de Silverlight utilizan “Async” como sufijo debido a que siempre son asincrónicos, o sea, cuando los llamamos no se detiene la ejecución de la aplicación hasta obtener el valor solicitado, sino que se ejecutan de forma paralela y luego se llama a un evento determinado al finalizar la consulta, en nuestro caso, LoginCompleted, LogoutCompleted y IsLoggedInCompleted respectivamente.
Para nuestro ejemplo vamos a crear una grilla en la página principal de nuestra aplicación donde agregaremos tres botones para realizar el login, logout y consultar si el usuario está logeado:

<Grid x:Name="LayoutRoot">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <StackPanel Orientation="Horizontal" Grid.ColumnSpan="2">
        <TextBlock Text="Usuario:" />
        <TextBox x:Name="txtUser" />
        <TextBlock Text="Contraseña:" />
        <PasswordBox x:Name="txtPassword" />
    </StackPanel>

    <Button x:Name="btnLogin" Content="Login" Grid.Row="1" Click="btnLogin_Click" />
    <Button x:Name="btnLogout" Content="Logout" Grid.Row="2" Click="btnLogout_Click" />
    <Button x:Name="btnIsLogedIn" Content="IsLogedIn" Grid.Row="3" Click="btnIsLogedIn_Click" />

    <TextBlock x:Name="lblLogin" Grid.Column="1" Grid.Row="1" />
    <TextBlock x:Name="lblLogout" Grid.Column="1" Grid.Row="2" />
    <TextBlock x:Name="lblIsLogedIn" Grid.Column="1" Grid.Row="3" />

    <TextBlock Text="Hora último resultado:" Grid.Row="4" />
    <TextBlock x:Name="lblTime" Grid.Column="1" Grid.Row="4" />
</Grid>

Y por último vamos a agregar el código que maneja los eventos de los botones del ejemplo:

private void btnLogin_Click(object sender, RoutedEventArgs e)
{
    lblLogin.Text = string.Empty;
    ServiceReference1.AuthenticationServiceClient objWSAuth = new ServiceReference1.AuthenticationServiceClient();
    objWSAuth.LoginCompleted += new EventHandler<ServiceReference1.LoginCompletedEventArgs>(objWSAuth_LoginCompleted);
    objWSAuth.LoginAsync(txtUser.Text, txtPassword.Password, string.Empty, true);
}

void objWSAuth_LoginCompleted(object sender, ServiceReference1.LoginCompletedEventArgs e)
{
    lblLogin.Text = e.Result.ToString();
    lblTime.Text = DateTime.Now.ToLongTimeString();
}

private void btnLogout_Click(object sender, RoutedEventArgs e)
{
    lblLogout.Text = string.Empty;
    ServiceReference1.AuthenticationServiceClient objWSAuth = new ServiceReference1.AuthenticationServiceClient();
    objWSAuth.LogoutCompleted += new EventHandler<AsyncCompletedEventArgs>(objWSAuth_LogoutCompleted);
    objWSAuth.LogoutAsync();
}

void objWSAuth_LogoutCompleted(object sender, AsyncCompletedEventArgs e)
{
    lblLogout.Text = "Listo";
    lblTime.Text = DateTime.Now.ToLongTimeString();
}

private void btnIsLogedIn_Click(object sender, RoutedEventArgs e)
{
    lblIsLogedIn.Text = string.Empty;
    ServiceReference1.AuthenticationServiceClient objWSAuth = new ServiceReference1.AuthenticationServiceClient();
    objWSAuth.IsLoggedInCompleted += new EventHandler<ServiceReference1.IsLoggedInCompletedEventArgs>(objWSAuth_IsLoggedInCompleted);
    objWSAuth.IsLoggedInAsync();
}

void objWSAuth_IsLoggedInCompleted(object sender, ServiceReference1.IsLoggedInCompletedEventArgs e)
{
    lblIsLogedIn.Text = e.Result.ToString();
    lblTime.Text = DateTime.Now.ToLongTimeString();
}

Para probar este ejemplo tenemos que tener configurada nuestra aplicación para que utilice un proveedor de membership, por ejemplo, SqlMembershipProvider, el cual se explica en el artículo de Dario (https://www.programandoamedianoche.com/2009/10/autenticacion-por-formularios-en-asp-net/2). Luego, a través de la herramienta de configuración de ASP.NET (ASP.NET Configuration) a la que se puede acceder a través del menú “Project” del Visual Studio, podemos crear usuarios de prueba ingresando en “Security” y luego “Create User”.

Crear usuario
Descargar proyecto de ejemplo para utilizar Autenticación de ASP.NET desde SilverlightComo siempre les dejo el proyecto para que lo prueben.
¡Suerte!

0 comentarios »

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.