Busca lo que quieras

Compartir sesión de autenticación entre dominios diferentes en .net

A veces necesitamos pasar un usuario con una sesión a otro sitio web con otro dominio distinto.... ¿Y cómo se hace eso? A continuación relataré varios pasos a tener presentes, espero sea claro, y les sirva.

-----------------PASOS DE INFRAESTRUCUTURA-------------------

1. Simular dominios distintos en nuestro IIS Local. Para lograrlo:
 - Nos metemos a:
C:\Windows\System32\drivers\etc\host y colocamos las ultimos lineas creando dos dominios locales:

127.0.0.1 www.testlocalhost1.com
127.0.0.1 www.testlocalhost2.com

2. Crear directorios virtuales en nuestro IIS Local.... crear un directorio virtual por cada sitio.

3. Probamos que podamos ingresar a nuestros sitios con los dominios creados así:
http://www.testlocalhost1.com/midirectoriovirtual/Default.aspx

http://www.testlocalhost2.com/midirectoriovirtual2/Default.aspx

4. Una vez aseguremos que nuestro sitio esta funcionando... procedemos ahora si a hacer el código:

-----------------PASOS DE CÓDIGO O IMPLEMENTACIÓN-------------------
1. En el sitio que va a enviar las credenciales vamos a crear una pagina que se llame:
Crear una pagina en el sitio desde el cual vamos a enviarle la sesión:
Esta pagina puede llamarse: Redirect.aspx y con su correspondiente Redirect.aspx.cs.
En el aspx vamos a colocar:
///////////////////////
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Redirect.aspx.cs"
    Inherits="Redirect" Theme="" StylesheetTheme="" %>

<!DOCTYPE html>
<html>
<head id="Head" runat="server">
   
</head>
<body>
    <form id="form1" runat="server">

       <div>
    <p>
<input id="hdnStreetCred" runat="server" type="hidden" />
<asp:Button ID="btnTransfer" runat="server" Text="Go" PostBackUrl="http://www.testlocalhost2.com/titanmulticlient2/Recieve.aspx" /></p>
   
  </div>
             
    </form>    
</body>
</html>


////////////////////////
en el cs vamos a colocar:
/////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Security.Cryptography;
using System.Threading;
using System.Web.Security;

public partial class Redirect : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
       
FormsIdentity cIdentity = Page.User.Identity as FormsIdentity;
if (cIdentity != null)
{
this.hdnStreetCred.ID = FormsAuthentication.FormsCookieName;
this.hdnStreetCred.Value = FormsAuthentication.Encrypt(((FormsIdentity)User.Identity).Ticket);
}
    }
    protected void BtnContinuar_Click(object sender, EventArgs e)
    {
        Response.Redirect("~/Default.aspx");
    }
}
/////////////////////////

Listo... hemos terminado la implementación del sitio que va a enviar la sesión.... Ahora vamos a pasar a la implementación del código en el sitio que va a recibir la sesión, así:

Vamos a crear una página que se llame:
Recieve.aspx que puede contener:
/////////////
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Recieve.aspx.cs" Inherits="Receive" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
    </div>
    </form>
</body>
</html>

////////////
Y en el cs debe contener:
/////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Security.Cryptography;
using System.Threading;
using System.Web.Security;

public partial class Receive : System.Web.UI.Page
{
   
    protected void Page_Load(object sender, EventArgs e)
    {
        HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName];
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
     

        if (!Context.User.Identity.IsAuthenticated)
        {
            Response.Redirect("Login.aspx");
        }
        else
        {
            Response.Redirect("Miperfil.aspx");
        }

    }
}
////////////

Muy bien!, ya hemos terminado la parte del código.... ahora vamos a definir una configuración muy importante en nuestros web.config de cada aplicación:
En el web.config de la aplicación que envia la sesión debemos de colocar:

 <forms loginUrl="Default.aspx" name=".ASPXFORMSAUTH" cookieless="UseCookies" slidingExpiration="true" timeout="1440" enableCrossAppRedirects="true" protection="All"
path="/" domain=".testlocalhost1.com" />

Y en la etiqueta: system.web
<machineKey validationKey="E0D7098C31ECF04C53AE8A4384BD67FDAC8F2145CA836A69ECE1166E1E0130628833BD9C09B50D13DEC6983FEBF9DE53F13764DDBB85F50DFDC3702710557E74" decryptionKey="FF4CF08FD21691CE5226C7A4A0C67E9B8584CB444E150F99899199EB631007CE" validation="SHA1" decryption="AES" />
------------------
En el web.config de la aplicación que recibe la sesión debemos de colocar:
 <forms loginUrl="Default.aspx" name=".ASPXFORMSAUTH" cookieless="UseCookies" slidingExpiration="true" timeout="1440" enableCrossAppRedirects="true" protection="All"
path="/" domain=".testlocalhost2.com" />

y en la etiqueta: system.web
<machineKey validationKey="E0D7098C31ECF04C53AE8A4384BD67FDAC8F2145CA836A69ECE1166E1E0130628833BD9C09B50D13DEC6983FEBF9DE53F13764DDBB85F50DFDC3702710557E74" decryptionKey="FF4CF08FD21691CE5226C7A4A0C67E9B8584CB444E150F99899199EB631007CE" validation="SHA1" decryption="AES" />

Como notan, las configuraciones son identicas y lo único que difiere es el atributo domain del tag forms.

Digamos que sin ir al fondo del como funciona nos damos cuenta de que .NET lo hace practicamente automatico... en el load de la pagina Receive.aspx, si colocamos un punto de interrupción (se puede hacer desde visual estudio en boton derecho sobre sitio web, y attach IIS.), nos daremos cuenta que .NET automaticamente detecta al usuario como logeado. Definitivamente algo muy automatico y maravilloso... je je.

Espero les sirva y no me haya faltado nada.... esto me consumió aprox. unas 16 horas de busqueda en google y desde luego gracias a internet y a personajes colaborativos en al red... desde luego especialmente a craigmoliver  que me ayudo con el primer paso.
en la página:
http://stackoverflow.com/questions/72125/how-do-you-pass-an-authenticaticated-session-between-app-domains

Notas finales:
Por seguridad y para que funcione la sesión debe guardarse en cookies, no por Uri... por eso el atributo llamado cookieless debe estar en: UseCookies.

Para el tema del machine key se puede utilizar una herramienta online para crear el machinekey que recordebemos debe ser el mismo en los sitios web que compartan sesión. La url es:
http://aspnetresources.com/tools/machineKey

Espero les sirva.

Sean felices! :) Y siéntanse libres de opinar ;)

No hay comentarios:

Publicar un comentario

Palabras Clave

.NET (93) AJAX (2) ajaxcontroltoolkit (2) Algoritmos (1) android (1) Angular (1) Arrays (1) AS2 o ActionScript 2.0 (1) AS3 o ActionScript 3.0 (64) ASP (7) ASP.NET (3) Azure (1) Azure DevOps (2) Backup (2) Batch (4) blogger (1) Browser Support (2) C# (53) Charts (1) Chorme extensions (1) Chrome (3) cmd (18) código postal (1) Colombia tips (1) command (1) Conexion remota (1) Controles Web .NET (24) Cookies (1) cordova (1) CSS (14) CSV (5) Cufon (1) DateTime (2) deployment (2) Desarrollo movil (2) Desarrollo web (5) Diseño (4) DNN o DotNetNuke (5) docker (1) Encuestas (1) Entity Framework (1) Error (1) Eval (2) Excel (4) Expresiones regulares (2) Facebook (14) fechas (1) Fiddler (1) FileUpload (1) Filezilla (1) Firefox (2) Flash (9) Fonts (3) FQL (1) frameworks (2) Futuro de la web (1) git (1) Google Code (13) Google Maps (4) hackintosh (3) hazard 10.6.2 (3) herramientas para developers (1) highchart (1) Hilos (2) Hosting Windows (18) HTML (38) HTML5 (6) IDE (1) IE (2) IE9 (1) IIS (13) imagenes (3) jasmine (2) java (1) jqgrid (2) Jquery y Javascript (90) jquery-ui (5) jQueryMobile (1) JSON (1) knockout (4) library (1) Link Interesantes (2) List (1) Macro (2) Matemáticas (2) Membership (6) Memoria (1) Mis Experiencias (3) momentjs (1) ms-dos (1) MSN (1) MVC (1) MVC4 (3) MySQL (2) node.js (4) Notepad++ (3) Notificaciones (1) ObjectDataSource (2) Online (2) Opinión (4) OSX (3) Parallels Plesk Panel (1) petapoco (1) PhantomJS (1) PHP (4) Porqué este blog (1) Powershell (1) Razor (3) Redes (2) REGEX (4) REST (1) SDK Android (1) Seguridad (1) SelectParameters (1) Selenium (2) sencha (3) sencha cmd (2) SEO (1) SMTP (2) Software útil (8) Solución (1) Soporte (1) SQL (15) SQL Server (58) SQLite (2) Store Procedures (20) String (5) Testing Code (2) texto (2) tips de datos (1) tips de desarrollo (1) TutoFaceAS3 (4) TutoProAS3 (4) Tutoriales (7) Tweenlite effects (3) Últimas noticias (1) unit testing (1) usb (1) VBA (1) Video (1) virus (1) Web API (2) Web Browsers (1) Web Forms (7) web.config (1) Webmaster (8) Webmatrix (1) webrole (1) webservices (1) webstorm (1) Win Forms (5) Windows (21) Windows 7 (1) Windows 8 (1) XML (2) Youtube API (2)