Ir al contenido principal

Autenticación de Aplicaciones

Un problema común a la hora de desarrollar aplicaciones es que a veces es necesario un conjunto de aplicaciones que forman parte de un sistema o arquitectura compleja, por lo que se hace necesario la autenticación de usuarios en cada una de ellas.

¿Qué sucede?

Creamos aplicaciones windows forms, wpf, asp.net o servicios wcf con su propia base de datos y generamos los usuarios y contraseñas necesarios para conceder el acceso a cada una de forma descentralizada y con diferentes roles y permisos.

¿Cuál es la propuesta?

Generar un mecanismo seguro, robusto y escalable de autenticación centralizado que pueda ser usado para autenticarnos desde cualquiera de nuestras aplicaciones.

La solución

Windows Identity Foundation, es una API dentro de .NET Framework con soporte para firmas digitales y basada en tokens, adicionado con soporte para realizar autenticación por formularios, windows, de dos pasos, usando servicios externos o servicios tales como Facebook, Google, Twitter Outlook, Linked-In y otros de manera simple.

El detalle

La API está pensada para implementarse en ASP.NET y WCF. ¿Qué pasa si quiero utilizar este mecanismo robusto de autenticación?

El Objetivo de Este POST

Darle la vuelta a esta restricción y poder utilizar este mecanismo de autenticación desde cualquier tipo de aplicación (Windows Forms, WPF, etc.).

Veamos primero su implementación en el siguiente video...

 

AccountController

/// <summary>
/// Método personalizado de autenticación desde aplicaciones que no son ASP.NET ni WCF
/// </summary>
/// <param name="userName">Nombre de usuario a validar</param>
/// <param name="password">Contraseña asociada</param>
/// <returns>Resultado de la autenticación en formato Json</returns>
[AllowAnonymous]
[HttpPost]
public JsonResult ApplicationLogin(string userName, string password)
{
    // Hace uso de la infraestructura WIF para llevar a cabo la autenticación
    var result = SignInManager.PasswordSignIn(userName, password, false, true);
    // Devuelve una cadena con el resultado en formato Json
    return Json(result.ToString());
} 

DLL ClienteAplicación

/// <summary>
/// Objeto Request
/// </summary>
public class LoginRequest{
    #region Propiedades

   
/// <summary>
    /// Nombre de usuario
    /// </summary>

    public string UserName { get; set; }
    /// <summary>
    /// Contraseña
    /// </summary>
    public string Password { get; set; }

    #endregion
}

/// <summary>
/// Clase intermedia de autenticación
/// </summary>
public class Cliente
{
    #region Campos
 
    private WebClient _webClient = null;
    private string _baseUrl = null;

    #endregion

    #region Constructor
    /// <summary>
    /// Recibe como parámetro la url a la que se enviará la petición de autenticación
    /// </summary>
    /// <param name="url">Url donde está hospedada la clase de autenticación</param>

    public Cliente(string url)
    {
        _webClient =
new WebClient();
        _baseUrl = url;
 
         if (string.IsNullOrEmpty(_baseUrl))        {            throw new ArgumentNullException("Es necesaria la url a la que se enviará la petición");
        }
    }


    #endregion

    #region Métodos
   
/// <summary>
    /// Realiza la petición de autenticación y regresa el resultado
    /// </summary>
    /// <param name="request">Objeto que contiene el usuario y contraseña a validar</param>
    /// <returns>Resultado de la autenticación</returns>

    public async Task<string> Login(LoginRequest request)
    {
        // Serialización del objeto request en formato Json
        var data = await Task.Factory.StartNew<string>(() => JsonConvert.SerializeObject(request));        // Prepara el cliente para llevar a cabo la petición
        _webClient.Headers.Add(HttpRequestHeader.ContentType, "application/json");
        // Realiza la petición y devuelve el resultado a su llamador
        return await _webClient.UploadStringTaskAsync(_baseUrl, "POST", data);
    }
 
    #endregion
}

Petición Desde Windows Forms Usando un Botón

/// <summary>
/// Realiza la petición de autenticación usando la DLL intermedia
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void button1_Click(object sender, EventArgs e)
{
    // Genera el objeto Request
    LoginRequest request = new LoginRequest() { 
        UserName = textBox1.Text, 
        Password = textBox2.Text 
    };
    // Genera y envía la url al objeto Cliente
    Cliente client = new Cliente("http://localhost:4343/Account/ApplicationLogin");
    // Realiza la petición de autenticación
    var result = await client.Login(request);
    // Muestra en un MessageBox el resultado de la autenticación
    MessageBox.Show(result.ToString());
}

Comentarios

Entradas más populares de este blog

Publicación de WCF en Net.TCP

Una de las grandes características de WCF es la forma en como éstos pueden ser expuestos a nuestros clientes, por ejemplo los siguientes protocolos, de manera muy recurrente: Http TCP Net Pipe ¿Sabes en que casos usar cada uno? Http cuando el servicio y el cliente se encuentran en redes diferentes TCP cuando el servicio y el cliente se encuentran en la misma red, pero en equipos diferentes Net Pipe cuando el servicio y el cliente se encuentran alojados en el mismo equipo ¿Por qué razón? Por cuestiones de redimiento y seguridad de la información Si una petición http toma un tiempo de 200 ms, por poner un ejemplo Una petición tcp tomará aproximadamente el 20% menos que la petición http (40 ms aproximadamente) Y una petición Net Pipe , tomará aproximadamente el 80% del tiempo que toma el hacer una petición tcp (32 ms aproximadamente) Para mayor entendimiento, chequen este post que alguna vez consultamos para entender un poco más acerca de éstos conceptos: https://j...

Validación de Fechas con jQuery Validator

Al validar fechas con jQuery Validate nos encontramos con el problema de que dicha validación se hace en formato: MM/DD/YYYY, esto es correcto, pero no tanto para formato de fechas de México al menos que es más común para nosotros hacerlo de manera que dicho formato sea: DD/MM/YYYY. Para poder solucionar este problema haremos algunas modificaciones en las librerías: jquery.validate.js jquery.validate.min.js Veamos el siguiente video para la implementación de dicha solución: jquery.validate.js Se deja comentado el cómo se hace la validación original y se adiciona el código personalizado que permite validar el formato de fecha del tipo: DD/MM/YYYY 1 2 3 4 5 6 7 8 9 10 11 // http://jqueryvalidation.org/date-method/ // Nivisix Soluciones: personalización para formato de fechas DD/MM/YYYY date : function ( value, element ) { //return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() ); var com...

SQLServer Stored Procedure Para Ordenar Columnas Ascendente / Descendente

Pues este es nuestro primer post referente a SQLServer ... En primera instancia les queremos platicar qué es lo que buscamos:  Mediante un stored procedure obtener un listado ordenado por alguna de las columnas devueltas de manera ascendente o descendente, dependiendo de los parámetros de entrada del mismo. Muchas de las ocasiones cuando nos ha tocado buscar información acerca de cómo hacer este proceso, solemos encontrar recomendaciones de hacerlo usando un query que se contruye en tiempo de ejecución usando una variable de tipo VARCHAR(MAX) y después hacer uso de la función EXEC para ejecutarlo. Al final, se resuelve el problema, pero la intención es mejorar el procedimiento sin afectar el rendimiento y evitando problemas de seguridad como el SQL Injection . Veamos un video con una propuesta diferente de resolución de este requerimiento: Creación de la Base de Datos Usando el siguiente query que pueden ejecutar en el cliente base de datos SQL Server creare...