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...
¿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());
/// </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
/// 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
/// </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;
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
#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() {
/// </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());
// 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
Publicar un comentario