12 de enero de 2016

jQuery UI Dialog Modal Popup Confirm ASP.NET

Para trabajar con estos ejemplos se necesitan las librerías de jquery, jquery-ui y los temas de jquery-ui, por mi parte he creado dos carpetas una para las librerías JQuery(Scripts) y otra para los temas css(Content), la llamada a las librerías queda de la siguiente manera:



igualmente los ejemplos trabajan con CDN



Primera Aproximación.
En este ejemplo se mostrara una ventana que le pide al usuario confirmación para mostrar eliminar un usuario, se mostrarán dos opciones: Yes-NO y la lógica e la siguiente: al dar click sobre el botón con ID=btnDelete

También se debe especificar en un elemento DIV el mensaje que se desea mostrar, esto significa colocar codigo HTML en la pagina ASP del servidor, voy a mostrar la imagen pues quien sabe porque el syntax highlighter que utilizo para mostrar código no me permite especificar los <> de la etiqueta div
se verifica con un if si tiene un atributo relacionado con valor "delete" en caso de no existir significa que no se ha mostrado la ventana de confirmación y la muestra, en caso de existir el atributo con valor "delete" relacionado al botón con ID=btnDelete entonces llama al método especificado en OnClick y pasa el control al servidor, esto se logra con la función __doPostBack() y se le pasa como parámetro el id del botón para que sepa a que método en el servidor debe ser dirigido.

Notar que autoOpen esta en false pues la ventana modal aparecerá a petición de otra función o condición y no al instante de dar click sobre el boton, en este caso, al no darse la condición if ($(this).attr("rel") != "delete") dentro de la captura del evento click del botón se mostrara la ventana modal, caso contrario no.

el código en el servidor puede realizar una conexión a la base de datos que elimine el registro, en este ejemplo solo mostrare un mensaje que indique que el registro fue eliminado exitosamente
protected void btnDGV_Click(object sender, EventArgs e)
{
 ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('Registro eliminado exitosamente !!!')", true);
}
un inconveniente que puede darse utilizando esta primera aproximación es que debe crearse un elemento DIV de HTML en la pagina web de ASP para especificar el mensaje a mostrar, seria mejor que este se creara desde JQuery, esto se trata a continuación.

Segunda Aproximación.
Este segundo ejemplo además de especificar el método del servidor mediante el evento OnClick del boton, tambien se utilizara OnClientClick para obtener una confirmación vía Jquery UI que el usuario realmente desea eliminar el registro, primero muestro el botón con sus propiedades

En este ejemplo no es necesario especificar en un elemento DIV de HTML cual sera el mensaje a mostrar en la ventana JQuery UI emergente, esta es una ventaja al menos desde mi punto de vista pues puedes tener el mensaje especificado en un archivo con extensión .js y después solo referenciar desde tu pagina web sin necesidad de llenar de elementos DIV la pagina, de eta manera quien se encargue de las validaciones(o si eres tu quien programa del lado cliente y del servidor) tendrán mas orden y podrán realizar los cambios pertinentes sin tocar el código de servidor.

La lógica es esta: al presionar el botón el evento OnClientClick nos enviara a la funcion de JavaScript especificada, en este caso nos envía a confirmCheckIn la cual recibe como parámetro el button, también contamos con una variable _confirm con un valor inicial de false pues asumimos que el cliente no quiere borrar el registro, luego con Jquery creamos un elemento div y especificamos un mensaje html para este, también se especifican los botones que son los que al presionarlos cambiaran o mantendrán el valor de la variable _confirm, al final de la función retornamos el valor final de la variable _confirm que es lo que esta esperando el boton para saber que accion realiza, en caso de ser true la página entrega el mando al servidor que llama al método especificado en el evento OnClick del botón.

Notar que autoOpen es true pues el dar click sobre el botón implícitamente indica que abrirá la ventana modal, seria false si esperara por una función/condición que evaluara si presentar la ventana o no.

si el método del servidor del servidor es llamado, de nuevo solo muestro un mensaje que indique que el registro fue eliminado exitosamente
protected void btnDGV_Click(object sender, EventArgs e)
{
 ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('Registro eliminado exitosamente !!!')", true);
}

Tercera Aproximación.
Como ultimo ejemplo muestro el mas basico o al menos el mas utilizado, se captura el evento click del botón mediante JQuery y se utiliza e.preventDefault() para evitar que el botón ejecute el método de servidor especificado en la propiedad OnClick, primero muestro el codigo del control button ASP

La lógica es esta: al dar click sobre el botón se previene el envío de la pagina al servidor utilizando e.preventDefault() y luego utilizando JQuery se crean dos etiquetas: DIV y SPAN, para mostrar el mensaje. En caso se presione el botón Yes, se utiliza unbind() sobre el botón con id=btnCancel, esta sentencia provocará se descarten que todos los manejadores de eventos asociados al clic sobre el botón. Como se puede entender, sobre este botón no ocurrirá nada en el momento en que hagamos clic. Además, en el supuesto que otros scripts Javascript hayan definido algún manejador de evento clic sobre alguno de los elementos, unbind() también eliminará esos posibles eventos.

Por último al presionar Yes se le permite al boton llamar al método definido en su evento onclick utilizando document.getElementById('<%= btnCancel.ClientID %>').click()

Notar que autoOpen es true pues el dar click sobre el botón implícitamente indica que abrirá la ventana modal, seria false si esperara por una función/condición que evaluara si presentar la ventana o no.

y de nuevo, si el método del servidor es llamado, muestro un mensaje indicando que el registro fue eliminado
protected void btnDGV_Click(object sender, EventArgs e)
{
 ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('Registro eliminado exitosamente !!!')", true);
}
Aproximación General
Que pasa si tenemos una pagina web que requiere varias confirmaciones por parte del usuario para realizar operaciones sobre una base de datos, digamos que presenta al usuario la oportunidad de realizar un CRUD sobre una base de datos, que hacemos en ese caso? creamos un script utilizando jQuery para cada botón o creamos un script general que reciba útil para todos los botones que presenten un mensaje de confirmación a los usuarios y simplemente le mandamos un mensaje a la función javascript a fin de personalizar el mensaje? ... ... ...

Pues me parece acertada la ultima opcion y sobre esa se va trabajar en este post para empezar voy a agregar al formulario web cinco botones, puede ser exagerado pero la idea es mostrar las ventajas de utilizar una función javascript para mostrar mensajes de confirmación de diferentes acciones

como ven cada botón tiene un diferente valor en su evento onclick, pero el mismo valor en su evento onclientclick, la diferencia vienen en los dos primeros parámetros que se le envían a la función pues representan los mensajes que deseamos que la ventana de confirmación presente, notar que el tercer parámetro es una referencia sobre el botón en el que se dio el click, aqui dejo la funcion javascript

  






la función trabaja así:
1. Desde el botón se utiliza el evento onclientclick para invocar a la función javascript, a esta función se le pasan tres parámetros, dos de tipo string y una referencia al botón que invoca la función, así:
onclientclick="return confirmCheckIn('Desea eliminar el registro', 'Confirmacion eliminacion...', this);"
2. Como pueden ver este botón en su propiedad onclientclick espera una confirmación(true or false) de parte de la función javascript a la que invoca, así que lo primero que se debe hacer es crear una variable con un valor por defecto false ya que por defecto no queremos que al presionar el botón se nos envíe directamente al servidor se reciben los mensajes.
3. si se presiona el botón Yes de la confirm dialog box entonces el valor de la variable confirm cambia a true y regresa al mando al evento click del botón que invoco la función, importantísimo colocar esta linea de codigo button.click();
4. En caso de presionar No, simplemente cierra la ventana modal de confirmación y no cambia el valor de la variable por lo que se retorna false.

5 de enero de 2016

Seguridad Transport - Message utilizando wsHttpBinding

WCF Transport Security
Protege la información a través del canal de comunicación entre el cliente y el servidor, el tipo de canal utilizado para enviar la informacion define cual sera el protocolo a utilizar para encriptar y autentificar la información, por ejemplo HTTPS utiliza SSL o bien el que tu especifiques en el binding


Supongamos que utilizaremos un servicio WCF para trabajar en la web utilizando el protocolo HTTP, en este caso HTTPS proporciona integridad, confidencialidad y autenticación de servidor y la seguridad del mensaje SOAP proporciona la autenticación del cliente.De manera predeterminada, se realiza la autenticación del cliente una vez por sesión y los resultados de autenticación están almacenados en la memoria caché durante la duración de la sesión, ejemplo:






WCF Message Security
La seguridad aquí se expresa en que el mensaje es encriptado ante de utilizar cualquiera sea el medio de transporte de la información entre cliente y servidor, de esta forma solo las partes que conocen como desencriptar el mensaje podrán leerlos.

Cuando se crea un servicio WCF y se desea brindar seguridad a nivel de mensaje se deben utilizar certificados digitales de tipo x.509 los cuales brindan un nivel de confianza para el envío de credenciales desde el cliente al servidor, ejemplo:

  
    
      
    
  
antes de comenzar muestro los bindings de WCF y el tipo de seguridad que brindan


En esta entrada se utilizara un WCF Service con wsHttpBinding, este servicio solo expondrá una operacion
public string saludo(string nombre)
 {
  return string.Format("Hola {0} este servicio WCF utiliza wsHttpBinding", nombre);
 }
Se trabajara con un WCF Service hospedado en IIS, también será de importancia en este ejemplo el descargar pluralsight que es una herramienta que ayuda a crear certificados útiles en la etapa de desarrollo, otro aspecto a recalcar que se van a validar credenciales de un cliente(username y password) por tanto se debe agregar la clase UserNameValidator a nuestro servicio WCF, esta clase hereda de de la clase UserNamePasswordValidator y sobreescribe el método Validate, ademas se debe agregar la referencia a la dll System.IdentityModel no solo en el código de la clase sino también "manualmente"
using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

namespace WCFWSBinding
{
 public class UserNameValidator : UserNamePasswordValidator
 {
  public override void Validate(string userName, string password)
  {
   if (string.IsNullOrEmpty(userName))
   throw new ArgumentNullException("userName");
 
   if (string.IsNullOrEmpty(password))
   throw new ArgumentNullException("password");

   if (userName == "Pablo" && password == "Pablo")
   return;
   throw new SecurityTokenException("Unknown Username or Password");
  }
 }
}

Creando el certificado x509

Lo primero sera crear el certificado que se va utilizar ya sea en seguridad WCF modo transporte o seguridad WCF modo message, en esta entrada se utilizara la herramienta PluralSight Self-Cert, lo primero sera descargar la herramienta y ejecutarla en modo administrador


Como nombre utilizare CertWCF y se alojara en mi computadora de trabajo


Al presionar el botón Save tendremos una pantalla con los detalles del certificado recién creado que ademas nos muestra el mensaje que nuestro certificado ha sido creado y guardado, pero si presionamos el botón View Cert... 


nos damos cuenta que nuestro certificado recién creado no es de confianza para la computadora, esto pasa porque un certificado debe ser aprobado por una autoridad certificadora y en esta entrada así como en algunos proyectos de desarrollo se utilizan certificados auto-aprobados, lo que haremos es presionar el botón Install Certificate


seleccionamos Local Machine y presionamos el botón Next


Seleccionamos la primera opcion y luego presionamos el botón Next


para completar la validación de nuestro certificado presionamos el botón Finish


tendremos de nuevo la pantalla con los detalles del certificado, ahor presionamos el botón Browse Store


buscamos en la lista de certificados el CertWCF y damos click sobre este


y podemos verificar que ahora nuestro recién creado certificado si es de confianza para la computadora


Pero aun no terminamos, en la ventana de Command Prompt de Windows escribe mmc y luego enter, aparecerá una ventana de User Account Control, sobre esta presiona el botón Yes



En esta nueva ventana selecciona File --> Add/Remove Snap-in...


Selecciona Certificate en el panel izquierdo y luego presiona el boton Add


selecciona Computer Account y presionar el botón Next


seleccionamos Local Computer


presionar OK


en la carpeta Personal debe aparecer el certificado CertWCF, dar click derecho y copiar


Pegar el certificado en carpeta Trusted People y cerrar


Ahora abrimos el administrador de IIS y sobre nuestro servidor buscamos Server Certificates


Aparecerá nuestro certificado CertWCF recién creado


Lo que sigue es agregar un binding de tipo Https a nuestro sitio web, para ello damos click derecho sobre el sitio y seleccionamos Edit Bindings...


seleccionamos https


y seleccionamos el certificado CertWCF recién creado


El binding recién agregado debe estar disponible para el sitio


Transport Security with Certificate Authentication

the service is hosted under Internet Information Services (IIS) which is configured with Secure Sockets Layer (SSL). The service is configured with an SSL (X.509) certificate to allow clients to verify the identity of the server. The client is also configured with an X.509 certificate that allows the service to verify the identity of the client. The server’s certificate must be trusted by the client and the client’s certificate must be trusted by the server.



Continuando con nuestro ejemplo, se debe especificar que nuestro sitio web exija el utilizar SSL, para ello desde el administrador de IIS nos posicionamos en nuestro servicio WCF y buscamos SSL Settings, dar doble click sobre este y seleccionar Require SSL 



Después de lo anterior viene la configuracion del Web.config, les dejo la configuracion del Web.config que a mi me ha funcionado para trabajar con seguridad WCF en modo transporte, por alguna razón el blogger o el SyntaxHighlighter(que es la herramienta que ocupa para mostrar el código en blogger) me cambia el orden del codigo cuando se trata de XML y ademas me crea la etiqueta system. web="" donde debería ser system.web  y también coloca system. servicemodel="" donde debería ser system.servicemodel, les dejo la imagen de esa parte especifica del Web.config para que lo tengan en cuenta por si no les parece correcta correcta esa etiqueta o por si son los que le dan copy-paste al código(aparte del orden y de las etiquetas mencionadas el código funciona) y después de la imagen que muestra las etiquetas antes mencionadas y el orden de los atributos dejo el código XML de la configuración


  
      
  
  
   
    
      
             
          
          
             
            
          
           
          
         
       
      
    
    
    
      
        
        
        
         
          
             
          
        
      
    

    
      
        
          
          
          
          
            
                 
        
        
      
    
    
    
    
    
    
      
        
          
        
      
    
  
  
    
    
  
  
  
  
    
      
        
          
        
      
      
        
          
        
      
    
    
      
    
    
  

ahora toca agregar un cliente que consumirá nuestro recién creado servicio WCF, para ello utilizare una aplicacion de escritorio y agregare una referencia al servicio WCF utilizando la dirección Https asi:


antes de mostrar el código del cliente para hacer llamado al servicio WCF hay que hacer notar que aunque se haya creado un certificado para pruebas en etapa de desarrollo, este no esta debidamente validado y al IIS no se le puede engañar, asi que cuando hagamos peticiones desde el cliente podemos encontrarnos con este error 


para evitar ese error se debe agregar esta linea de codigo:
System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => true;
pero solo durante la etapa de desarrollo, cuando tu proyecto pase a producción recuerda quitarla y contar con un certificado debidamente validado y quitar la linea de código, aqui esta la llamada al servicio WCF desde el cliente:
private void enlazar_Click(object sender, EventArgs e)
 {
 System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => true;
 string saludo = string.Empty;
 using (pruebaHttps.WSBindingClient proxy = new pruebaHttps.WSBindingClient())
  {
  proxy.ClientCredentials.UserName.UserName = "Pablo";
  proxy.ClientCredentials.UserName.Password = "Pablo";
  try
   {
   saludo = proxy.saludo(txt.Text.ToString());
   MessageBox.Show(saludo);
   }
   catch (Exception ex) {
   MessageBox.Show(ex.Message.ToString());
   }             
  }
 }

Message Security with a User Name Client

Desde el sitio de microsoft https://msdn.microsoft.com/en-us/library/ms731058(v=vs.110).aspx lo exponen de la siguiente manera



Si vienes trabajando desde la seguridad WCF modo transporte(caso contrario dirígete al código XML del Web.config) lo primero a destacar aquí es que ya no se necesita que nuestro servicio WCF requiera SSL así que desmarcamos esta opción desde el IIS Manager


también en el Web.config del servicio WCF se debe cambiar baseaddress="https://localhost/WCFWSBinding/Service1.svc" por baseaddress="http://localhost/WCFWSBinding/Service1.svc"

 
   
  
 

y cambiar el binding="mexHttpsBinding" por binding="mexHttpBinding"

por ultimo cambiar httpsgetenabled="true" por httpgetenabled="true"

La configuración del Web.config queda de la siguiente manera manera, primero muestro la imagen del Web.config y después muestro el código XML, esto lo hago porque les recuerdo mi problema: por alguna razón el blogger o el SyntaxHighlighter(que es la herramienta que ocupa para mostrar el código en blogger) me cambia el orden del código cuando se trata de XML y ademas me crea la etiqueta system. web="" donde debería ser system.web  y también coloca system. servicemodel="" donde debería ser system.servicemodel



y aqui esta el codigo XML 


  
      
  
  
    
      
             
          
          
            
              
            
           
          
        
      
    
    
      
        
          
            
            
          
        
        
        
          
            
          
        
      
    
    
      
        
          
          
          

                   
            
            
           
            
                 
        
        
      
    
    
    
    
      
        
          
        
      
    
  
  
    
    
  
  
  
  
    
      
        
          
        
      
      
        
          
        
      
    
    
      
    
    
  

se agrega una referencia de servicio al cliente, en este ejemplo utilizare una aplicación de Windows Forms como cliente


el código con el que se solicita un método del servicio WCF desde el cliente es
private void enlazar_Click(object sender, EventArgs e)
 {  
  string saludo = string.Empty;
           
   using (pruebaCert.WSBindingClient proxy = new pruebaCert.WSBindingClient())
   {
    proxy.ClientCredentials.UserName.UserName = "Pablo";
    proxy.ClientCredentials.UserName.Password = "Pablo";
     try
     {
     saludo = proxy.saludo(txt.Text.ToString());
     MessageBox.Show(saludo);
     }
     catch (Exception ex)
     {
     MessageBox.Show(ex.Message.ToString());
     }        
   }
 }
y el código en el App.config del cliente(utilizo Windows Forms como cliente) se tiene esta configuración