Autenticación con Facebook utilizando OWIN Katana

Antes de hablar sobre Owin y OAuth. Permíteme describirte qué significan estas dos palabras:

Owin: Es un acrónimo de Open Web Interface for .NET. Se trata de una nueva interfaz estándar entre el servidor web y las aplicaciones web, lo cual significa romper el estrecho acoplamiento entre ASP.NET e IIS. Si estás desarrollando aplicaciones web en único framework y en una única plataforma de servidor, puedes ignorar OWIN.

Entonces, ¿qué es Katana?

OWIN es sólo una especificación. Es un acto de identificar algo con precisión o de plantear una exigencia precisa. Katana es un componente de Microsoft que implementa requisitos OWIN.

Entonces, ¿qué es OAuth?

Es una autorización estándar de código abierto que proporciona una aplicación cliente "asegurando el acceso delegado". OAuth se utiliza comúnmente para usuarios de Internet que se conectan a sitios webs de terceros como Microsoft, Google, Facebook o Twitter sin exponer su contraseña.

Si tengo que resumir lo anterior en pocas palabras:
OWIN se utiliza para la autenticación (quién eres).
OAuth se utiliza para la autorización (lo que puede hacer).

Cada vez que solicitamos en el mundo Http cada petición, se trata como una petición individual, es por eso que al Http lo llamamos como protocolo sin estado. Para crear un estado utilizamos las cookies o las sesiones.

Las cookies se pueden clasificar como

First Party Cookie: Si el nombre del host es el mismo que el dominio de la barra de direcciones del navegador cuando se establece o se recupera, entonces es una First Party Cookie. Las First Party Cookies solamente se establecen o se recuperan mediante las páginas webs cuando las visitas, por lo que normalmente no se pueden utilizar para realizar un seguimiento de la actividad o pasar datos de un sitio a otro

Third Party Cookie: Si el dominio del host para una cookie es diferente al de la barra de direcciones del navegador cuando se descargó, entonces es una Third Party Cookie. Por ejemplo, cuando visitas un sitio que contiene un vídeo de YouTube en una de sus páginas. Esto ha sido incluido por el propietario del sitio web, con un trozo de código proporcionado por YouTube. YouTube será entonces capaz de establecer las cookies a través de este código, y saber que has visto ese vídeo, o incluso saber desde qué página estás viendo el vídeo.

Cookie de sesión: Las cookies de sesión sólo se almacenan temporalmente en la memoria del navegador, y se destruyen cuando este se cierra. Si necesitas hacer login en un sitio web cada vez que abres tu navegador, entonces es que esa web utiliza una cookie de sesión para almacenar tus credenciales.

Cookies persistentes: Cada vez marcamos el control "No cerrar sesión", significa que una creamos y almacenamos una cookie persistente del lado del cliente, si no, no se llamaría cookie persistente.

Cookies seguras: Las cookies seguras sólo se transmiten a través de HTTPS - protocolo que se suelen encontrar en tiendas online o en páginas donde debes proporcionar tus datos bancarios.

El código

Con el propósito de crear nuestra aplicación OWIN, vamos a empezar por crear un proyecto ASP.NET mediante una plantilla vacía. Dado que no necesitamos de la funcionalidad de ASP.NET, hemos comenzado con una plantilla vacía.

Ve al Package Manager Console

PM>Install-Package Microsoft.Owin.Host.SystemWeb
PM> Install-package Microsoft.AspNet.WebApi.Owin

Crea una carpeta llamada controller y añade el nuevo archivo de la clase como MyLandingPageController y asegúrate de que la clase base es el controlador.

Crea una carpeta llamada views. Esto ayudará a añadir la vista.

public class MyLandingPageController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
<html>
<body>
<div>
      <h2>Hi, Welcome to My Landing Page. You are authorized to view my Page :)</h2>
</div>
</body>
</html> 

Abre el archivo Global.asax y añade las líneas de abajo en el evento application_start

protected void Application_Start()
{
 RouteTable.Routes.MapRoute(name: "Default",
                url: "{controller}/{action}",
                defaults: new { controller = "MyLandingPage", action = "Index" });
}
<html>
<body>
<div>
     <h1> This is my Landing Page. Now You are Authenticated to View My Page....</h1>
</div>
</body>
</html>

Cuando ejecutes la aplicación se redigirá automáticamente y obtendrás un pantallazo tal que así:

Pero sin autenticación es posible ver la landing page. Esto no es correcto. ¿Que debemos hacer entonces? Añade [Authorize] debajo de MyLandingPageController. Pulsa f5 y verás que ahora obtienes un error 401.0 de página no autorizada, lo que significa que te hacen falta las credenciales.

Ahora ve y añade el AuthController

public class AuthController : Controller    
{        
  public ActionResult Login()        
  {    
     var model = new LoginModel();
     return View(model);
  }

 [HttpPost]
 public ActionResult Login(LoginModel login)
 {
     if (login.UserName.Equals("som", StringComparison.OrdinalIgnoreCase) && login.Password == "som") 
     var identity = new ClaimsIdentity("ApplicationCookie");
     identity.AddClaims(new List
     {
        new Claim(ClaimTypes.NameIdentifier, login.UserName),
        new Claim(ClaimTypes.Name, login.UserName)
     });
     HttpContext.GetOwinContext().Authentication.SignIn(identity); 
   }
   return View(login);
 }

 public ActionResult Logout()
 {
   HttpContext.GetOwinContext().Authentication.SignOut();
   return Redirect("/");
 }
}

Ahora voy a crear una clase de Bootstrap para inicializar mi aplicación. Crea el fichero de la clase y llámalo startup. Esto tendrá el siguiente código. Aquí "ApplicationCookie" es el nombre de la cookie que se creará y se enviará al cliente para la autenticación.

[assembly: OwinStartup(typeof(.StartUp))]
namespace OWIN_MVC
{
  public class StartUp
    {
       public static void Configuration(IAppBuilder app)
       {
            app.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions
            {
                AuthenticationType = "ApplicationCookie",
                LoginPath = new PathString("/Auth/Login")
            });
       }
     }
}

Ahora esto redirigirá automaticamente a tu página de login. Una vez introduzcas las credenciales correctas, serás capaz de ver la pantalla autorizada.

Utilizando las herramientas adecuadas puedes ver que la cookie de sesión se mantiene en el navegador. Tal y como te he inidicado antes, una vez cierres el navegador, la cookie se destruirá. Una vez más, tienes que proporcionar la credencial adecuada para ver la página MyLanding. Hasta ahora no nos conectamos al third party. Vamos a centrarnos en esto.

Si deseas conectarte a una third party no podrás utilizar el IIS Express debido a que facebook no aceptará la solicitud del host local. Así que tenemos que hacer algún cambio en el entorno de desarrollo para falsificar la URL.

Ve a Ejecutar => Controlador => etc => abrir archivo hosts y añadir nueva entrada

127.0.0.1 www.somowin.demo

Crea un nuevo sitio web en el IIS y como nombre pon www.somowin.demo. Ahora puedes acceder a tu aplicación como muestro a continuación.

Una vez termines de hacer todo esto, hay realizar un pequeño ajuste en Facebook.

Ve a developers.facebook.com/apps => Agregar nueva App => Página web => Crear una nueva aplicación de Facebook => Nómbrala como "Som Owin Demo" y marca la categoría "Educación". Una vez que ya hayas creado la app, ve a MyApps y copia el AppID y el App Secret de la aplicación.

Ve a la Configuración de tu app en FB y haz clic en Opciones avanzadas donde verás el campo OAuth URL. A continuación ingresa la URL donde deseas redirigir.

Ahora necesitas hacer algunos cambios en tu código para conectarlo con tu app de Facebook. Necesitamos instalar el paquete microsoft.owin.security.facebook, y en la clase de startup tenemos que ingresar el AppID y el App Secret que hemos copiado de la página de Facebook.

[assembly: OwinStartup(typeof(.StartUp))]
namespace OWIN_MVC
{
  public class StartUp
    {
       public static void Configuration(IAppBuilder app)
       {
            app.UseFacebookAuthentication(new FacebookAuthenticationOptions
            {
              AppId= "",
              AppSecret="",
              SignInAsAuthenticationType="ApplicationCookie"
            });

            app.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions
            {
                AuthenticationType = "ApplicationCookie",
                LoginPath = new PathString("/Auth/Login")
            });



       }
     }
}

En el AuthController, voy a añadir un método más para el Facebook login

public class AuthController : Controller    
{        
  public ActionResult Login()        
  {    
     var model = new LoginModel();
     return View(model);
  }

 [HttpPost]
 public ActionResult Login(LoginModel login)
 {
     if (login.UserName.Equals("som", StringComparison.OrdinalIgnoreCase) && login.Password == "som") 
     var identity = new ClaimsIdentity("ApplicationCookie");
     identity.AddClaims(new List
     {
        new Claim(ClaimTypes.NameIdentifier, login.UserName),
        new Claim(ClaimTypes.Name, login.UserName)
     });
     HttpContext.GetOwinContext().Authentication.SignIn(identity); 
   }
   return View(login);
 }

 public ActionResult Logout()
 {
   HttpContext.GetOwinContext().Authentication.SignOut();
   return Redirect("/");
 }

  
public ActionResult LoginFacebook()
{
   HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties
   {
     RedirectUri="/MyLandingPage"
   },"Facebook");
   return new HttpUnauthorizedResult();
 }

}

Cambia la vista que muestra el botón de login de Facebook.

@inherits System.Web.Mvc.WebViewPage<OWIN_MVC.Models.LoginModel>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Login</title>
</head>
<body>
    <div>
        @using (var form = Html.BeginForm())
        {
            <div>
                @Html.LabelFor(x => x.UserName)
                @Html.TextBoxFor(x => x.UserName)
            </div>
             <div>
                @Html.LabelFor(x => x.Password)
                @Html.PasswordFor(x => x.Password)
            </div>
            <div>
                <input type="submit" value="Login" />
            </div>

            <div>
                <div>@Html.ActionLink("Log in With a Facebook", "LoginFaceBook")</div>
            </div>
}
        
    </div>
</body>
</html>

Ahora ya todo debe funcionar correctamente.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP