-
Aplicaciones web
Tras haber visto en qu consiste el desarrollo de interfaces web,
las alternativas de las quedispone el programador y el modelo
concreto de programacin de las pginas ASP.NET weben la plataforma
.NET, pasamos ahora a estudiar cmo se construyen aplicaciones web
reales,en las cuales suele haber ms de una pgina:
- Primero tendremos que aprender a dominar algunos detalles de
funcionamientodel protocolo HTTP, el protocolo a travs del cual el
navegador del usuarioaccede al servidor web donde se aloja nuestra
aplicacin ASP.NET.
- Acto seguido, veremos cmo ASP.NET nos facilita mantener
informacin comna varias solicitudes HTTP realizadas
independientemente; esto es, lo que seconoce en el mundo de las
aplicaciones web como sesiones de usuario.
- Finalmente, cerraremos el captulo describiendo cmo podemos
controlar a qupartes de la aplicacin puede acceder cada usuario,
cmo crear formularios deautentificacin y darle permisos al usuario
para que realice determinadas tareas enel servidor.
Otros aspectos de inters relacionados con la organizacin interna
de las aplicacionesASP.NET los dejaremos para el siguiente captulo.
Por ahora, nos centraremos en lascuestiones que afectan ms
directamente al uso de nuestra aplicacin por parte del usuario.
-
Aplicaciones webEl protocolo HTTP
.................................................................87
En el camino correcto
.............................................. 90Control del trfico
con manejadores y filtros HTTP . 91Cuestin de
refresco................................................
95Almacenamiento en cach.......................................
97
En el navegador web del cliente............................
97... y en el servidor
web........................................... 99
Cookies
....................................................................
99
Sesiones de usuario en
ASP.NET......................................103El contexto de una
pgina ASP.NET..................... 103Mantenimiento del estado de
una aplicacin web . 105
Seguridad en ASP.NET
.......................................................111Autentificacin
y autorizacin ................................ 111Autentificacin en
Windows................................... 114Formularios de
autentificacin en ASP.NET.......... 116Permisos en el servidor
......................................... 119Seguridad en la
transmisin de datos.................... 120
86 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
El protocolo HTTP
El protocolo HTTP [HyperText Transfer Protocol] es un protocolo
simple de tiposolicitud-respuesta incluido dentro de la familia de
protocolos TCP/IP que se utiliza enInternet. Esto quiere decir que,
cada vez que accedemos a una pgina (en general, a un
recursoaccesible a travs de HTTP), se establece una conexin
diferente e independiente de lasanteriores.
Funcionamiento del protocolo HTTP: Cada solicitud del cliente
tiene comoresultado una respuesta del servidor y, cada vez que el
cliente hace una
solicitud, sta se realiza de forma independiente a las
anteriores.
Internamente, cuando tecleamos una direccin de una pgina en la
barra de direcciones delnavegador web o pinchamos sobre un enlace,
el navegador establece una conexin TCP conel servidor web al que
pertenece la direccin especificada. Esta direccin es una URL de
laforma http://... y, salvo que se indique lo contrario en la
propia URL, la conexin conel servidor se establecer a travs del
puerto 80 TCP. Una vez establecida la conexin, elcliente enva un
mensaje al servidor (la solicitud) y ste le responde con otro
mensaje (larespuesta). Tras esto, la conexin se cierra y el ciclo
vuelve a empezar. No obstante, hay que
87Aplicaciones web
http://csharp.ikor.org/
-
mencionar que, por cuestiones de eficiencia y para reducir la
congestin en la red, HTTP/1.1mantiene conexiones persistentes, lo
cual no quiere decir que la interaccin entre cliente yservidor vare
un pice desde el punto de vista lgico: cada par solicitud-respuesta
esindependiente.
Informacin tcnica acerca de InternetComo se ver con ms detalle
en el captulo dedicado a lacreacin de aplicaciones distribuidas con
sockets, los puertosson un mecanismo que permite mantener varias
conexionesabiertas simultneamente, lo que se conoce
comomultiplexacin de conexiones. Los protocolos TCP y UDPincluyen
este mecanismo para que, por ejemplo, uno puedaestar navegando por
Internet a la vez que consulta el correo oaccede a una base de
datos.
Toda la informacin tcnica relacionada con los
estndaresutilizados en Internet se puede consultar
enhttp://www.ietf.org, la pgina web del Internet EngineeringTask
Force. IETF es una comunidad abierta que se encarga degarantizar el
correcto funcionamiento de Internet por mediode la elaboracin de
documentos denominados RFCs [RequestFor Comments]. Por ejemplo, la
versin 1.0 del protocoloHTTP est definida en el RFC 1945, mientras
que laespecificacin de la versin 1.1 de HTTP se puede encontraren
el RFC 2616.
El protocolo HTTP slo distingue dos tipos de mensajes,
solicitudes y respuestas, que sediferencian nicamente en su primera
lnea. Tanto las solicitudes como las respuestas puedenincluir
distintas cabeceras adems del cuerpo del mensaje. En el cuerpo del
mensaje es dondese transmiten los datos en s, mientras que las
cabeceras permiten especificar informacinadicional acerca de los
datos transmitidos. En el caso de HTTP, las cabeceras siempre son
dela forma clave: valor. Un pequeo ejemplo nos ayudar a entender el
sencillofuncionamiento del protocolo HTTP.
Cuando accedemos a una pgina web desde nuestro navegador, la
solicitud que se le remite alservidor HTTP es de la siguiente
forma:
GET http://csharp.ikor.org/index.html HTTP/1.1If-Modified-Since:
Fri, 31 Oct 2003 19:41:00 GMTReferer:
http://www.google.com/search?...
La primera lnea de la solicitud, aparte de indicar la versin de
HTTP utilizada (1.1 en este
88 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
caso), tambin determina el mtodo utilizado para acceder al
recurso solicitado. Este recursoha de venir identificado mediante
un URI [Universal Resource Identifier], tal como se defineen el
estndar RFC 2396. Los mtodos de acceso ms usados son GET y POST,
que slo sediferencian en la forma de pasar los parmetros de los
formularios. Existe otro mtodo, HEAD,que slo devuelve metadatos
acerca del recurso solicitado.
Tras la primera lnea de la solicitud, pueden o no aparecer lneas
adicionales en las cuales seaade informacin relativa a la solicitud
o al propio cliente. En el ejemplo,If-Modified-Since sirve para que
el cliente no tenga que descargar una pgina si stano ha cambiado
desde la ltima vez que accedi a ella en el servidor. Por su parte,
Refererindica la URL del sitio desde el que se accede a la pgina,
algo de vital importancia siqueremos analizar el trfico de nuestro
servidor web. Incluso existen cabeceras, comoUser-Agent, mediante
las cuales podemos averiguar el sistema operativo y el navegadorque
usa el cliente al acceder al servidor HTTP.
El final de una solicitud lo marca una lnea en blanco. Esta lnea
le indica al servidor HTTPque el cliente ya ha completado su
solicitud, por lo que el servidor puede comenzar a generarla
respuesta adecuada a la solicitud recibida. Dicha respuesta puede
ser el aspecto siguiente:
HTTP/1.1 200 OKServer: Microsoft-IIS/5.0Date: Sun, 17 Aug 2003
10:35:30 GMTContent-Type: text/htmlLast-Modified: Tue, 27 Mar 2001
10:34:52 GMTContent-Length: XXX
--- Aqu se enva el texto de la pgina HTML
Como se puede apreciar, en la primera lnea de la respuesta
aparece la versin de HTTPempleada, un cdigo de estado de tres
dgitos y una breve descripcin de ese cdigo deestado. A continuacin,
aparecen una serie de cabeceras en las que se puede identificar
elservidor HTTP que realiza la respuesta (Server), la fecha (Date),
el tipo MIMEcorrespondiente a los datos que se envan con la
respuesta (Content-Type), la ltima vezque se modific el fichero
devuelto (Last-Modified) y la longitud del fichero de datosque se
manda como respuesta a la solicitud (Content-Length, donde XXX
representa, enuna respuesta real, el nmero de bytes de datos que se
transmiten). Finalmente, la respuestaconcluye enviando los datos
asociados al recurso que solicit el cliente, un fichero HTML
talcomo indica el tipo de la respuesta (text/html).Como se puede
apreciar, en la cabecera de la respuesta HTTP se incluyen bastantes
datos quepueden resultar de inters a la hora de controlar la
interaccin entre el cliente y el servidor.Respecto al primero de
esos datos, el cdigo de estado devuelto en la primera lnea de
larespuesta HTTP, la siguiente tabla resume las distintas categoras
a las que pueden pertenecer:
89Aplicaciones web
http://csharp.ikor.org/
-
Cdigo Significado Ejemplos1xx Mensaje informativo2xx xito 200
OK
3xx Redireccin 301 Moved Permanently302 Resource temporarily
moved
4xx Error en el cliente 400 Bad request401 Unauthorized403
Forbidden
5xx Error en el servidor 500 Internal Server Error
Los apartados siguientes nos mostrarn cmo podemos hacer uso de
nuestro conocimiento delfuncionamiento interno del protocolo HTTP
para realizar determinadas tareas que puedensernos de inters en la
creacin de aplicaciones web.
En el camino correctoComo cualquier programador que se precie
debe saber, lo ideal a la hora de desarrollar unsistema de cierta
complejidad es dividir dicho sistema en subsistemas lo ms
independientesposibles. En el caso particular que nos ocupa, cuando
tenemos una aplicacin web conmultitud de pginas ASP.NET, lo ideal
es que cada pgina sea independiente de las demspara facilitar su
mantenimiento y su posible reutilizacin.
Esta independencia resulta prcticamente imposible de conseguir
si no separamos la lgica decada pgina de la lgica encargada de la
navegacin entre las distintas partes de la aplicacin.Adems, tampoco
nos gustara que la lgica encargada de la navegacin por las
distintaspartes de nuestra aplicacin apareciese duplicada en cada
una de las pginas de sta. En elsiguiente captulo se tratar con
mayor detalle cmo organizar la aplicacin para mantener
suflexibilidad sin que exista cdigo duplicado. Por ahora, nos
conformaremos con ver cmopodemos controlar dinmicamente las
transiciones de una pgina a otra sin que estastransiciones tengan
que estar prefijadas en el cdigo de la aplicacin.La implementacin
de las redirecciones resulta trivial en ASP.NET. Cuando
queremosredirigir al usuario a una URL concreta, lo nico que
tenemos que escribir es lo siguiente:
Response.Redirect("http://csharp.ikor.org");
90 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
El mtodo Redirect de la clase HttpResponse redirige al
explorador del cliente a laURL especificada utilizando la respuesta
HTTP adecuada, mediante el uso del grupo decdigos de estado 3xx
(vase la tabla anterior).Cuando lo nico que queremos es enviar al
usuario a otra pgina ASP.NET de nuestra propiaaplicacin, podemos
utilizar el mtodo Transfer de la clase HttpServerUtility.Basta con
teclear:
Server.Transfer("bienvenida.aspx");
En este caso, la redireccin se realiza internamente en el
servidor y el navegador del usuariono es consciente del cambio de
pgina. Esto resulta ms eficiente que enviarle un cdigo deredireccin
al navegador del usuario pero puede producir resultados no deseados
si el usuarioactualiza la pgina desde la barra de botones de su
navegador.
Algo tan sencillo como las redirecciones nos puede servir, no
slo para decidir en tiempo deejecucin la siguiente pgina que se le
ha de mostrar al usuario, sino tambin para configurardinmicamente
nuestra aplicacin. Por ejemplo, podemos almacenar en un fichero XML
lasURLs correspondientes a los distintos mdulos de una aplicacin y,
en funcin del contenidode ese fichero, decidir a dnde debemos
dirigir al usuario. Esto no solamente disminuye elacoplamiento
entre las distintas pginas de la aplicacin y su ubicacin fsica ,
sino quetambin facilita la implantacin gradual de nuevos sistemas
conforme se van implementandonuevos mdulos. Adems, en vez de que
cada pgina sea responsable de decidir a dnde ha dedirigirse el
usuario (lo que puede ocasionar problemas de consistencia), se
puede garantizar larealizacin de las acciones de coordinacin
adecuadas a lo largo y ancho de la aplicacin.Simplemente, se
elimina de las pginas individuales la responsabilidad de
coordinarse con lasdems pginas de la aplicacin, disminuyendo el
acoplamiento e implementado la cohesinde las distintas pginas.
Control del trfico con manejadores y filtros HTTPEn el apartado
anterior hemos visto cmo podemos controlar la navegacin por las
distintaspartes de una aplicacin web. Ahora veremos cmo podemos
controlar a bajo nivel laspeticiones que recibe nuestra aplicacin e
incluso llegar a interceptar las peticiones HTTPantes de que stas
sean atendidas por una pgina.
Control de las solicitudes HTTP
Por ejemplo, podramos centralizar el control de la navegacin por
nuestra aplicacin sicreamos un manejador que implemente la interfaz
IHttpHandler. Este manejador ser el
91Aplicaciones web
http://csharp.ikor.org/
-
que reciba todas las peticiones HTTP y decida en cada momento
cul es la accin msadecuada en funcin de la solicitud recibida. De
hecho, el interfaz IHttpHandler es labase sobre la que se montan
todas las pginas ASP.NET y nosotros, si nuestro problema
lojustifica, podemos acceder a bajo nivel a las solicitudes y
respuestas HTTP correspondientes ala interaccin del usuario con
nuestra aplicacin. ste es el aspecto que tendra
nuestromanejador:
using System;using System.Web;
public class Handler : IHttpHandler{public void ProcessRequest
(HttpContext context){Command command = ...
command.Do (context);}
public bool IsReusable{get { return true;}
}}
donde Command se utiliza para representar una accin concreta de
las que puede realizarnuestra aplicacin. Dicho objeto se
seleccionar en funcin del contexto de la solicitud HTTPrecibida;
por ejemplo, a partir de los valores de los parmetros de la
solicitud, a los que sepuede acceder con context.Request.Params. En
realidad, el objeto command seruna instancia de una clase que
implemente la interfaz Command:
using System;using System.Web;
public interface Command{void Do (HttpContext context);
}
De esta forma se aplica un conocido patrn de diseo para separar
la responsabilidad dedeterminar cul debe ser la accin que la
aplicacin ha de realizar, de lo que se encarga elmanejador, de la
ejecucin en s de la accin, de la que se encarga el objeto que
implemente lainterfaz Command. Este es el mismo esquema que se
utiliza, por ejemplo, para dotar a unprograma de la capacidad de
hacer y deshacer acciones. Para esto ltimo slo tendramos queaadir a
la interfaz Command un mtodo Undo que se encargase de deshacer
cualquiercambio que se hubiese efectuado al ejecutar el mtodo
Do.
92 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
Un lector observador se habr dado cuenta de que, hasta ahora,
hemos creado algunas clasespero an no las hemos enganchado a
nuestra aplicacin web para que hagan su trabajo. Enrealidad, lo
nico que nos queda por hacer es indicarle al servidor web que todas
laspeticiones HTTP que reciba nuestra aplicacin se atiendan a travs
de nuestro manejador.Esto se consigue aadiendo lo siguiente en la
seccin de un fichero XMLdenominado Web.config que contiene los
datos relativos a la configuracin de unaaplicacin ASP.NET:
donde Handler es el nombre de la clase que hace de manejador
yControladorWeb.dll es el nombre de la DLL donde est definido
nuestro controlador.
Siguiendo el esquema aqu esbozado se centraliza el trfico que
recibe nuestra aplicacin, conlo que se garantiza la consistencia de
nuestra aplicacin web y se mejora su flexibilidad a lahora de
incorporar nuevos mdulos. A cambio, el controlador incrementa algo
la complejidadde la implementacin y, si no es lo suficientemente
eficiente, puede crear un cuello de botellaen el acceso a nuestra
aplicacin.
Interceptacin de los mensajes HTTPPuede que estemos interesados
en tener cierto control sobre las solicitudes que recibe
nuestraaplicacin pero no deseemos llegar al extremo de tener que
implementar nosotros la lgicaque determine qu accin concreta ha de
realizarse en cada momento. En ese caso, podemosutilizar filtros
HTTP por los que vayan pasando las solicitudes HTTP antes de llegar
a lapgina ASP.NET. Esto puede ser til para monitorizar el uso del
sistema, decodificar losdatos recibidos o realizar tareas a bajo
nivel cualquier otra tarea que requieran elprocesamiento de las
solicitudes HTTP que recibe nuestra aplicacin (como pueden ser,
porejemplo, identificar el tipo de navegador que utilizan los
usuarios o la resolucin de supantalla).En los prrafos anteriores
describimos cmo podemos reemplazar el mecanismo habitual derecepcin
de solicitudes HTTP en las aplicaciones ASP.NET definiendo nosotros
mismos unaclase que implemente la interfaz IHttpHandler. Ahora
vamos a ver cmo podemosinterceptar esas mismas solicitudes sin
tener que modificar el modo de funcionamiento de laspginas ASP.NET
de nuestra aplicacin. Para ello, deberemos implementar un mdulo
HTTP.
Los mdulos HTTP son clases que implementan la interfaz
IHttpModule. Por ejemplo,SessionStateModule es un mdulo HTTP que se
encarga de la gestin de sesiones deusuario en ASP.NET, algo que
estudiaremos en la siguiente seccin de este mismo captulo.Los
mdulos HTTP se pueden usar para interceptar los mensajes HTTP
correspondientes a
93Aplicaciones web
http://csharp.ikor.org/
-
solicitudes y a respuestas en varios momentos de su
procesamiento, por lo que, alimplementar un mdulo HTTP, deberemos
decidir cundo se interceptarn los mensajes.El siguiente ejemplo
muestra cmo podemos crear un mdulo HTTP que mida el tiempo quese
tarda en atender cada solicitud y lo muestre al final de cada pgina
que ve el usuario:
using System;using System.Web;using System.Collections;
public class HttpLogModule: IHttpModule{public void
Init(HttpApplication application){application.BeginRequest += new
EventHandler(this.OnBeginRequest);application.EndRequest += new
EventHandler(this.OnEndRequest);
}
// Al comienzo de cada solicitud...
private void OnBeginRequest (Object source, EventArgs
e){HttpApplication application =
(HttpApplication)source;HttpContext context =
application.Context;context.Items["timestamp"] =
System.DateTime.Now;
}
// Al terminar de procesar la solicitud...
private void OnEndRequest (Object source, EventArgs
e){HttpApplication application =
(HttpApplication)source;HttpContext context =
application.Context;DateTime start = (DateTime)
context.Items["timestamp"];DateTime end = DateTime.Now;TimeSpan
time = end.Subtract(start);context.Response.Write("Tiempo empleado:
"+time);
}
public void Dispose(){}
}
Igual que suceda con los manejadores HTTP, el uso de mdulos HTTP
se indica en el ficherode configuracin de la aplicacin web, el
fichero Web.config:
94 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
donde HttpLog.HttpLogModule es el nombre de la clase que
implementa el interfazIHttpModule y HttpLog es el nombre de la DLL
en la que est definido el tipoHttpLog.HttpLogModule.
Al utilizarse un nico fichero de configuracin para toda la
aplicacin web, se evita tener queduplicar cdigo para realizar
tareas comunes a las distintas partes de la aplicacin. No sloeso,
sino que se pueden aadir y eliminar filtros dinmicamente mientras
la aplicacin estfuncionando, sin tener que modificar una sola lnea
de cdigo. Los filtros, adems, sonindependientes unos de otros, por
lo que se pueden combinar varios si es necesario. Incluso sepueden
reutilizar directamente en distintos proyectos, pues los filtros
slo deben dependen delcontexto de una solicitud HTTP.
Ya que los filtros se ejecutan siempre, para todas
lassolicitudes HTTP que reciba nuestra aplicacin, es esencialque su
ejecucin sea extremadamente eficiente. De hecho, losfiltros
implementados como mdulos HTTP tradicionalmentese han implementado
con lenguajes compilados como C oC++ usando ISAPI (un interfaz
especfico del IIS).
Cuestin de refrescoLas peculiaridades de las interfaces web
ocasionan la aparicin de problemas de los cuales notendramos que
preocuparnos en otros contextos. ste es el caso de un problema
bastantecomn con el que nos encontraremos siempre que nuestra
aplicacin web deba realizar unatarea relativamente larga. Lo que
est claro es que no queda demasiado bien de cara al usuariodejar su
ventana en blanco de forma indefinida mientras nuestra aplicacin
realiza losclculos que sean necesarios.
Una solucin ms elegante involucra la utilizacin de hebras. Como
se ver en la siguienteparte de este libro, las hebras nos permiten
ejecutar concurrentemente distintas tareas. Ennuestro caso, el
problema de realizar un clculo largo lo descompondremos en dos
hebras:
- La hebra principal se encargar de mostrarle al usuario el
estado actual de laaplicacin, estado que se refrescar en su
navegador automticamente gracias aluso de la cabecera Refresh,
definida en el estndar para las respuestas HTTP.
- Una hebra auxiliar ser la encargada de ejecutar el cdigo
correspondiente aefectuar todos los clculos que sean necesarios
para satisfacer la solicitud delusuario.
Dicho esto, podemos pasar a ver cmo se implementara la solucin
propuesta en laplataforma .NET. Comenzaramos por implementar
nuestra pgina ASP.NET:
95Aplicaciones web
http://csharp.ikor.org/
-
...
using System.Threading;
public class Payment : System.Web.UI.Page{
protected Guid ID; // Identificador de la solicitud
private void Page_Load(object sender, System.EventArgs e){if
(Page.IsPostBack) {
// 1. Crear un ID para la solicitudID = Guid.NewGuid();// 2.
Lanzar la hebraThreadStart ts = new
ThreadStart(RealizarTarea);Thread thread = new
Thread(ts);thread.Start();// 3. Redirigir a la pgina de
resultadosResponse.Redirect("Result.aspx?ID=" + ID.ToString());
}}
private void RealizarTarea (){...
Results.Add(ID, resultado);}...
}
La clase auxiliar Results se limita a mantener una coleccin con
los resultados de lasdistintas hebras que se hayan lanzado, para
que la pgina de resultados pueda acceder a ellos:
using System;using System.Collections;
public sealed class Results{private static Hashtable results =
new Hashtable();
public static object Get(Guid ID){return results[ID];
}
public static void Add (Guid ID, object result){results[ID] =
result;
}
public static void Remove(Guid ID){results.Remove(ID);
}
96 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
public static bool Contains(Guid ID){return
results.Contains(ID);
}}
Finalmente, la pgina encargada de mostrar los resultados se
refrescar automticamentehasta que la ejecucin de la hebra auxiliar
haya terminado y sus resultados estn disponibles:
public class Result : System.Web.UI.Page{protected
System.Web.UI.WebControls.Label lblMessage;
private void Page_Load(object sender, System.EventArgs e){Guid
ID = new Guid(Page.Request.QueryString["ID"]);
if (Results.Contains(ID)) {// La tarea ha terminado: Mostrar el
resultadolblMessage.Text =
Results.Get(ID).ToString();Results.Remove(ID);
} else {// An no tenemos el resultado: Esperar otros 2
segundosResponse.AddHeader("Refresh", "2");
}}...
}
Aunque pueda parecer algo complejo, la solucin aqu propuesta es
extremadamente til en laprctica. Imagine, por ejemplo, una
aplicacin de comercio electrnico que ha de contactarcon un banco
para comprobar la validez de una tarjeta de crdito. No resulta
demasiado difcilimaginar la impresin del usuario final cuando la
implementacin utiliza hebras y cuando nolo hace. En otras palabras,
siempre ser recomendable tener en cuenta la posibilidad deutilizar
hebras cuando el tiempo de respuesta de nuestra aplicacin afecte
negativamente a suimagen de cara al usuario.
Almacenamiento en cach
En el navegador web del cliente...Relacionado indirectamente con
el refresco de una pgina web se encuentra otra de lascabeceras
estndar que se pueden incluir en las respuestas HTTP. Nos estamos
refiriendo a lacabecera Cache-Control, que se utiliza en ocasiones
para disminuir el trfico en la red noaccediendo al servidor cada
vez que, a travs del navegador, se accede a una URL.
97Aplicaciones web
http://csharp.ikor.org/
-
Si bien el uso de cachs puede ser altamente recomendable para
mejorar el tiempo derespuesta de una aplicacin, al no tener que
acceder reiteradamente al servidor cada vez quese accede a un
recurso concreto, tambin es cierto que, en ocasiones, nos interesar
garantizarque no se utiliza ningn tipo de cach al acceder a
determinada URL. Esto se consigue con lasiguiente cabecera
HTTP:
Cache-Control: no-cache
Definicin de cabeceras HTTP especficas para modificar
elcomportamiento por defecto de una aplicacin web. En este caso,
para que
el usuario nunca acceda por error a versiones antiguas de las
imgenesalmacenadas en un directorio, se evita que su navegador
almacene copias
locales de estas imgenes.
98 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
Lo anterior es equivalente a incluir lo siguiente en el cdigo de
una pgina ASP.NET:
Response.AddHeader("Cache-Control", "no-cache");
De esta forma nos aseguraremos de que el usuario siempre acceder
a los datos ms recientesde los que se disponga en el servidor. En
el caso de la agenda de contactos utilizada comoejemplo en el
captulo anterior, cuando el usuario modifica la fotografa de una de
las entradasde la agenda, la nueva imagen sobreescribe a la imagen
antigua. En tal situacin, para mostraradecuadamente los datos de
una persona ser necesario deshabilitar la cach para lasimgenes,
pues si no el navegador del usuario volvera a mostrar la imagen que
ya tienealmacenada localmente y no la imagen que reemplaza a
sta.
... y en el servidor web
Independientemente del uso de cachs en HTTP, ASP.NET tambin
permite crear cachs depginas. Esto puede resultar til para pginas
que se generan dinmicamente pero no cambiandemasiado a menudo. El
uso de una cach de pginas tiene el nico objetivo de reducir lacarga
en el servidor y aumentar el rendimiento de la aplicacin web.
Para que una pgina ASP.NET quede almacenada en la cach de pginas
y no sea necesariovolver a generarla basta con usar la directiva
@OutputCache al comienzo del fichero.aspx. Por ejemplo:
La primera vez que se acceda a la pgina, la pgina ASP.NET se
ejecutar normalmente pero,al utilizar esta directiva, las
siguientes solicitudes que lleguen referidas a la misma
pginautilizarn el resultado de la primera ejecucin. Esto suceder
hasta que la pgina almacenadaen cach caduque, 60 segundos despus de
su generacin inicial en el ejemplo. Despus deesos 60 segundos, la
pgina se eliminar de la cach y en el siguiente acceso se volver
aejecutar la pgina (adems de volver a almacenarse en la cach
durante otros 60 segundos).
CookiesHTTP, por definicin, es un protocolo sin estado. Sin
embargo, al desarrollar aplicacionesweb, mantener su estado resulta
imprescindible. Por ejemplo, en un sistema de comercioelectrnico
debemos ser capaces de almacenar de alguna forma el carrito de la
compra de un
99Aplicaciones web
http://csharp.ikor.org/
-
cliente concreto.
Una primera solucin a este problema (no demasiado acertada, por
cierto) consiste engestionar sesiones utilizando cookies, tal como
se definen en el RFC 2965. Una cookie,"galletita", es una pequea
cantidad de datos almacenada en el cliente. En realidad, se
tratasimplemente de un par nombre-valor acompaado por una fecha de
caducidad. Los datos dela cookie se pasan al servidor como parte de
cada solicitud HTTP, de forma que la aplicacinweb tiene acceso
inmediato a esos datos del cliente. Adems, la aplicacin puede
manipular lacookie para almacenar los datos que le interesen en
cada momento.
Conforme se va navegando por Internet, muchos sitios van
generando cookies en el cliente.En principio, los datos incluidos
en la cookie slo puede utilizarlos el servidor que la cre. Laidea
es utilizar una cookie por servidor o grupo de servidores y que esa
cookie almacene en elcliente toda la informacin que pueda necesitar
el servidor. En el ejemplo del carrito de lacompra, la cookie podra
incluir la lista de artculos que deseamos comprar.
No obstante, obsrvese que los datos asociados a una cookie se
almacenan en la mquinacliente. Nada nos garantiza que los datos en
el cliente estn almacenados de forma segura. Dehecho, usualmente se
guardan sin ningn tipo de proteccin (bsquese, por ejemplo,
elsubdirectorio Cookies en Windows). Por tanto, siempre es
recomendable no almacenar enuna cookie datos que puedan poner en
peligro la privacidad del usuario. Si volvemos al casoanterior, lo
ms recomendable sera almacenar nicamente en la cookie un
identificador quenos permita identificar el carrito de la compra
del usuario. El contenido de dicho carritosiempre se mantendra a
buen recaudo en el servidor.
Por otro lado, el uso de cookies lo provoca el servidor y no el
cliente (Set-Cookie2), porlo que en determinadas situaciones puede
resultar conveniente configurar el cliente para queignore los
cookies, lo que se consigue no devolviendo la cabecera Cookie2
mostrada en elsiguiente diagrama:
100 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
Funcionamiento de las cookies
Las cookies se usan con frecuencia para mantener sesiones de
usuario (conjuntos deconexiones HTTP relacionadas desde el punto de
vista lgico) y tambin para analizar losusos y costumbres de los
usuarios de portales web. ste ltimo punto, llevado al extremo, eslo
que ha dado mala fama a la utilizacin de cookies y ha provocado que
muchos usuarios,celosos de su privacidad, deshabiliten el uso de
cookies en sus navegadores. En realidad, suuso proviene simplemente
del hecho de que mantener una pequea cantidad de datos en elcliente
simplifica enormemente el seguimiento de los movimientos del
usuario y descarganotablemente al servidor web, que no ha de
emplear tiempo en analizar de dnde viene cadasolicitud.
Aparte de los posibles problemas de privacidad que puede
ocasionar el uso de cookies,tambin hay que tener en cuenta que la
manipulacin de las cookies creadas por nuestraaplicacin web se
puede convertir en un arma de ataque contra nuestra propia
aplicacin, porlo que debemos ser extremadamente cuidadosos a la
hora de decidir qu datos almacenarn
101Aplicaciones web
http://csharp.ikor.org/
-
las cookies.
Vistos los pros y los contras del uso de cookies, slo nos falta
ver cmo se pueden utilizar enASP.NET. Como no poda ser de otra
forma, su utilizacin es muy sencilla. Basta con accedera las
propiedades Request.Cookies y Response.Cookies de la pgina
ASP.NET.Ambas propiedades devuelven una coleccin de cookies.
Para establecer el valor de una cookie, basta con escribir
Response.Cookies["user"]["name"] =
"BCC";Response.Cookies["user"]["visit"] =
DateTime.Now.ToString();
Para acceder a dichos valores bastar con teclear lo
siguiente:
string user = Request.Cookies["user"]["name"];DateTime visit =
DateTime.Parse(Request.Cookies["user"]["visit"]);
Por defecto, ASP.NET utiliza cookies para mantener el
identificador de la sesin de usuario.A partir de dicho
identificador, se pueden recuperar todos los datos relativos al
usuario de unaaplicacin web. De esto se encarga un filtro HTTP
denominado SessionStateModule.De hecho, una de las tareas tpicas de
los filtros HTTP en muchas aplicaciones es el control decookies con
diversos fines. Los datos relativos a la sesin de usuario se
almacenan en unobjeto de tipo Session que ser objeto de estudio en
la siguiente seccin de este captulo.
Aunque las cookies hayan recibido mucha publicidad, no sonel
nico mecanismo mediante el cual una aplicacin webpuede almacenar
informacin acerca del cliente. Otrasalternativas menos polmicas
incluyen el uso de camposocultos en los formularios HTML, el empleo
de parmetroscodificados en la propia URL o, incluso, la utilizacin
debases de datos auxiliares.
102 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
Sesiones de usuario en ASP.NET
En las ltimas pginas hemos analizado con relativa profundidad el
funcionamiento delprotocolo HTTP y tambin hemos visto cmo se pueden
aprovechar algunas de suscaractersticas para conseguir en nuestras
aplicaciones web el comportamiento deseado. Noobstante, los
mecanismos descritos se pueden considerar de "bajo nivel". Como
cabraesperar, la biblioteca de clases de la plataforma .NET nos
ofrece otros medios para desarrollaraplicaciones web sin necesidad
de tratar directamente con los detalles del protocolo HTTP. Enesta
seccin veremos algunas de las facilidades que nos ofrece la
plataforma .NET, es especialaqullas que nos facilitan el
mantenimiento del estado de una aplicacin web a pesar de questa est
montada sobre un protocolo sin estado como HTTP.
Obviamente, utilizar las facilidades ofrecidas por laplataforma
.NET no implica que el conocimiento delfuncionamiento interno de
una aplicacin web deje de sernecesario. Igual que de cualquier
programador se espera unconocimiento bsico de la arquitectura de un
ordenador y desu funcionamiento interno, un desarrollador de
aplicacionesweb debe ser consciente en todo momento de lo que
sucedepor debajo en una aplicacin de este tipo. Por este motivo
sele han dedicado bastantes pginas al estudio del protocoloHTTP
antes de pasar a temas ms especficos de ASP.NET.
El contexto de una pgina ASP.NETInternamente, todo ASP.NET se
construye a partir del interfaz IHttpHandler. Esteinterfaz, que ya
hizo su aparicin en el apartado anterior de este captulo cuando
vimos cmose pueden interceptar las solicitudes HTTP, define
nicamente dos mtodos:
IHttpHandler {void ProcessRequest (HttpContext context);bool
IsReusable ();
}
El mtodo ProcessRequest es el encargado de procesar una
solicitud HTTP concreta, a lacual se puede acceder utilizando el
objeto de tipo HttpContext que recibe comoparmetro. El otro mtodo,
IsReusable, sirve simplemente para indicar si una instancia de
103Aplicaciones web
http://csharp.ikor.org/
-
IHttpHandler puede utilizarse para atender distintas solicitudes
HTTP o deben crearseinstancias diferentes para cada solicitud
recibida.
A partir del interfaz IHttpHandler, si lo deseamos, podemos
construir nuestra aplicacinweb. Nos bastara con construir una clase
que implemente este interfaz y utilice sentencias deltipo
context.Response.Write("..."); para generar la pgina que ver
elusuario en su navegador. No obstante, esto no sera mucho mejor
que programar directamenteCGIs, por lo que recurriremos a una serie
de clases proporcionadas por ASP.NET parafacilitarnos el
trabajo.Como ya vimos en el captulo anterior, las pginas ASP.NET se
crean implementando unaclase derivada de System.Web.UI.Page en la
que se separa el cdigo de la presentacinen HTML. Internamente,
ASP.NET se encargar de compilar nuestra pgina construyendouna clase
que implemente la interfaz IHttpHandler.
Aparte de esta clase base a partir de la cual creamos nuestras
pginas y de todos los controlesASP.NET que nos facilitan la
programacin visual de los formularios web, ASP.NET nosproporciona
otro conjunto de objetos que nos permite gobernar la interaccin
entre el cliente yel servidor en una aplicacin web. Dentro de esta
categora, los objetos ms importantes conlos que trabajaremos en
ASP.NET se recogen en la siguiente tabla:
Objeto RepresentaHttpContext El entorno en el que se atiende la
peticin
Request La peticin HTTP realizada por el clienteResponse La
respuesta HTTP devuelta por el servidorServer Algunos mtodos
tiles
Application Variables globales a nivel de la aplicacin (comunes
a todas lassolicitudes recibidas desde cualquier cliente)
Session Variables globales a nivel de una sesin de usuario
(comunes atodas las solicitudes de un cliente concreto)
De los objetos recogidos en esta tabla, los dos ltimos son los
que nos permiten la interaccinentre el cliente y el servidor ms all
de los lmites de un formulario ASP.NET. En elprotocolo HTTP, cada
par solicitud/respuesta es independiente del anterior. Cuando
lainteraccin se limita a una misma pgina, ASP.NET se encarga de
mantener automticamenteel estado del formulario mediante el uso de
ViewState, tal como se describi al final delcaptulo anterior.
Cuando las solicitudes corresponden a pginas diferentes,
Application ySession nos permiten manejar con comodidad las
sesiones de usuario en ASP.NET.En otras palabras, mientras que
HttpContext, Request y Response proporcionan elcontexto de una
solicitud concreta, ViewState permite mantener el estado de un
formularioconcreto y, finalmente, Session y Application
proporcionan un mecanismo sencillo
104 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
para almacenar informacin acerca del estado de una aplicacin web
(a nivel de cada usuarioy a nivel global, respectivamente).
Mantenimiento del estado de una aplicacin webSi bien ASP.NET se
encarga de mantener el estado de una pgina ASP.NET, en cuanto
elusuario cambie de pgina (algo que suele ser habitual en cualquier
aplicacin web),tendremos que encargarnos nosotros de almacenar la
informacin de su sesin de algunaforma. Para resolver este problema
podemos optar por distintas alternativas:
- Almacenar la informacin de la sesin manualmente en el cliente,
para lo cual sepueden emplear cookies. Esta solucin hace uso del
protocolo HTTP a bajo nively puede resultar no demasiado buena en
funcin del tipo de aplicacin. Baste conrecordar la publicidad
negativa que ha supuesto para determinadas empresas eluso
indiscriminado de cookies.
- Otra opcin es crear algn tipo de mecanismo que nos permita
almacenarmanualmente en el servidor los datos de cada sesin de
usuario. Esta solucin,menos controvertida que la primera, puede
requerir un esfuerzo inicialconsiderable, si bien es cierto que
puede ser la solucin ptima en determinadosentornos distribuidos
(granjas de servidores, por ejemplo) y la nica viable sideseamos
construir un sistema tolerante a fallos.
- Por ltimo, podemos dejar que los datos relativos a las
sesiones se almacenenautomticamente si empleamos las ya mencionadas
colecciones Session yApplication. Dichas colecciones simplifican el
trabajo del programador y,como veremos, ofrecen bastante
flexibilidad a la hora de desplegar una aplicacinweb.
Las colecciones Session y Application, facilitadas por ASP.NET
para elmantenimiento de sesiones de usuario en ASP.NET, se pueden
ver como arrays asociativos.Un array asociativo es un vector al que
se accede por valor en vez de por posicin, igual quesucede en el
hardware que implementa las memorias cach de cualquier ordenador.
En ciertomodo, Session y Application pueden verse como diccionarios
en los que se utiliza unapalabra para acceder a su definicin. Esta
estructura de datos es muy comn en algunoslenguajes (AWK, por
ejemplo) y resulta fcil de implementar en cualquier lenguaje
quepermita sobrecargar el operador [] de acceso a los elementos de
un vector, como es el casode C#.
Para acceder a los datos de la sesin de usuario actual desde una
pgina ASP.NET, notenemos ms que utilizar la propiedad Session de la
clase que implementa la pginaASP.NET. La propiedad Session est
definida en la clase base System.Web.UI.Pagey, como todas las
pginas ASP.NET derivan de esta clase base, desde cualquier
pginaASP.NET se puede acceder directamente a la propiedad heredada
Session.
105Aplicaciones web
http://csharp.ikor.org/
-
Por ejemplo, en la pgina de entrada a nuestra aplicacin web
podramos encontrarnos algocomo lo siguiente:
void Page_Load (Object Src, EventArgs e){Session["UserName"] =
TextBoxUser.Text;
}
Una vez establecido un valor para nombre del usuario
correspondiente a la sesin actual,podemos utilizar este valor para
personalizar la presentacin de las pginas interiores de
laaplicacin:
labelUser.Text = (string) Session["UserName"];
Lo nico que nos falta por ver es cmo se pueden inicializar los
valores de las coleccionesSession y Application. Para ello hemos de
utilizar algunos de los eventos definidos enGlobal.asax.cs, un
fichero opcional en el que se incluye el cdigo destinado a
respondera eventos globales relacionados con una aplicacin ASP.NET.
En dicho fichero se define unaclase que hereda de
System.Web.HttpApplication y en la que se pueden implementarlos
mtodos Session_Start y Application_Start. Estos mtodos se
invocancuando comienza una sesin de usuario y cuando arranca la
aplicacin web, respectivamente,por lo que es en ellos donde se
deben inicializar las colecciones Session y Application.Aunque no
resulte de especial utilidad, podramos incluir algo como lo
siguiente en el ficheroGlobal.asax.cs:
void Session_Start(){Session["UserName"] = "";
}
La coleccin Session se puede considerar como una variable global
compartida por todaslas solicitudes HTTP provenientes de un mismo
usuario. Para saber a qu sesin correspondeuna solicitud HTTP
concreta se utiliza un identificador de sesin. Dicho identificador
segenera automticamente cuando el cliente accede por primera vez a
la aplicacin web y setransmite desde el cliente cada vez que ste
vuelve a acceder a cualquier pgina de laaplicacin web.
El identificador de la sesin es un nmero aleatorio de 120 bits
que se codifica como unacadena de caracteres ASCII, del estilo de
cqcgvjvjirmizirpld0dyi5, para que ningnusuario malintencionado
pueda obtener informacin til a partir de l. Dicho identificador
se
106 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
puede transmitir mediante una cookie o incrustado en la URL de
la solicitud, en funcin decmo se configure la aplicacin. Por
defecto, el identificador de la sesin (que no los datosasociados a
la sesin) se transmite utilizando la cookie ASP.NET_SessionId.
Cuando nose emplean cookies, el identificador de la sesin aparecer
como parte de la URL a la que seaccede:
http://servidor/aplicacin/(uqwkag45e35fp455t2qav155)/pgina.aspx
Para seleccionar la forma en la que deseamos transmitir el
identificador de la sesin, lo nicoque tenemos que hacer es
modificar el valor del atributo cookieless del elementosessionState
que aparece en el fichero de configuracin de nuestra aplicacin web,
unfichero XML llamado Web.config. Por defecto, este atributo tiene
el valor "false", queindica que se utilizar la cookie
ASP.NET_SessionId para almacenar el identificador dela sesin de
usuario:
Simplemente poniendo cookieless="true" podemos evitar el uso de
cookies enASP.NET. Lo que es an mejor, el fichero Web.config
permite configurar la forma en laque se almacenan los datos
correspondientes a las sesiones de los usuarios de
nuestraaplicacin. Slo tenemos que jugar un poco con la seccin
delfichero Web.config. A nuestra disposicin tenemos distintos
mecanismos para almacenarlos datos relativos a las sesiones de
usuario. La eleccin de uno u otro depender bsicamentedel entorno en
el que deba funcionar nuestra aplicacin.
Por defecto, los datos correspondientes a la sesin del usuario
se almacenan en el proceso delservidor que se encarga de ejecutar
las pginas ASP.NET, el proceso aspnet_wp.exe.ste es el mecanismo
utilizado por defecto, conocido como InProc:, y es el que aparece
enla seccin del fichero Web.config mostrado anteriormente.
Cuando una aplicacin web tiene muchos usuarios y un simple
ordenador no es capaz deatenderlos a todos a la vez, lo usual es
crear un cluster o granja de servidores entre los cualesse reparte
la carga de la aplicacin. El reparto de la carga se suele realizar
dinmicamente, porlo que las peticiones de un usuario concreto no
siempre las atiende el mismo servidor. Portanto, el estado de las
sesiones no puede almacenarse InProc, sino que ha de
centralizarseen algn sitio accesible desde cualquier servidor del
cluster.
107Aplicaciones web
http://csharp.ikor.org/
-
InProc: Los datos correspondientes a las sesiones de usuario se
almacenanen la memoria del proceso encargado de ejecutar las pginas
ASP.NET.
ASP.NET nos permite disponer de un proceso encargado de mantener
el estado de lasdistintas sesiones de usuario e independiente de
los procesos encargados de atender laspeticiones ASP.NET. Dicho
proceso (aspnet_state.exe) es accesible desde cualquierade los
servidores web y permite que las solicitudes HTTP puedan
enviarseindependientemente a cualquiera de los servidores
disponibles, independientemente de dndeprovengan. Para utilizar
este proceso independiente, conocido como "servidor de
estado",hemos de especificar el modo StateServer en la seccin del
fichero Web.config e indicar cul es la cadena de conexin que
permite acceder alservidor de estado. La cadena de conexin
consiste, bsicamente, en el nombre de la mquinaen la que se est
ejecutando dicho servidor de estado y el puerto TCP a travs del
cual sepuede acceder a l:
Por ltimo, ASP.NET tambin nos permite que los datos
correspondientes a las sesiones deusuario se almacenen de forma
permanente en una base de datos relacional (SQL*Server,como no poda
ser de otra forma). Esto permite que el estado de cada sesin se
mantengaincluso cuando falle alguna de las mquinas de la granja de
servidores (siempre y cuando nofalle la base de datos, claro est),
lo que permite a una aplicacin ASP.NET convencionalaspirar al mtico
24x7, funcionar 24 horas al da durante 7 das a la semana sin
interrupcinalguna.
108 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
StateServer: Despliegue de una aplicacin web ASP.NET en una
granja deservidores. El dispositivo NLB [Network Load Balancer] se
encarga derepartir la carga entre varios servidores, mientras que
los datos de las
sesiones de usuario se almacenan en el servidor de estado.
Para utilizar una base de datos SQL como soporte para el
mantenimiento de las sesiones deusuario, lo primero que tenemos que
hacer es crear la base de datos en el servidor SQL Serverque se
vaya a utilizar con este fin. Para ello, no tenemos ms que ejecutar
una de las macrossuministradas, InstallSqlState.sql para utilizar
una base de datos "en memoria"(TempDB) o InstallPersisSqlState.sql
para crear una base de datos (ASPState)que sobreviva ante posibles
cadas del SQL Server. A continuacin, ya en el ficheroWeb.config,
pondremos algo similar a lo siguiente:
109Aplicaciones web
http://csharp.ikor.org/
-
SqlServer: Uso de una base de datos SQL*Server para almacenar
los datoscorrespondientes a las sesiones de usuario.
Las facilidades ofrecidas por ASP.NET a travs de la modificacin
del fichero deconfiguracin Web.config nos permiten desplegar
nuestras aplicaciones ASP.NET endiversos entornos sin tener que
modificar una sola lnea de cdigo. En el caso de que el xitode
nuestra aplicacin lo haga necesario, podemos migrar nuestra
aplicacin de un servidor aun cluster sin forzar la afinidad de un
cliente a un servidor concreto, con lo que se mejora latolerancia a
fallos del sistema. Adems, el uso de una base de datos de apoyo nos
permitemantener el estado de las sesiones aun cuando se produzca
una cada completa del sistema. Laseleccin de una u otra alternativa
depender del compromiso que deseemos alcanzar entre laeficiencia y
la tolerancia a fallos de nuestra aplicacin web en lo que se
refiere almantenimiento de las sesiones de usuario.
Cuando utilizamos un servidor de estado fuera del
procesoencargado de atender las peticiones, en los modosStateServer
o SQLServer, los datos almacenados enlas sesiones del usuario han
de transmitirse de un proceso aotro, por lo que han de ser
serializables. Esto es, las clasescorrespondientes a los objetos
almacenados han de estarmarcadas con el atributo
[Serializable].
110 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
Seguridad en ASP.NET
A la hora de construir una aplicacin web, y especialmente si la
aplicacin se construye confines comerciales, es imprescindible que
seamos capaces de seguir los pasos de cada usuario.Adems, tambin
suele ser necesario controlar qu tipo de acciones puede realizar un
usuarioconcreto. De lo primero nos podemos encargar utilizando
mecanismos de control de sesionesde usuario como los vistos en el
apartado anterior. De lo segundo nos ocuparemos acontinuacin.
Aunque la seguridad es, por lo general, un aspecto obviado por
la mayor parte de losprogramadores a la hora de construir
aplicaciones, en un entorno web resulta esencial porquecualquiera
con una conexin a la red puede acceder a nuestras aplicaciones.
Planificar losmecanismos necesarios para evitar accesos no
autorizados a nuestras aplicaciones y serviciosweb se convierte,
por tanto, en algo que todo programador debera saber hacer
correctamente.
Cuando hablamos de seguridad en las aplicaciones web realizadas
bajo la plataforma .NET,en realidad nos estamos refiriendo a cmo
restringir el acceso a determinados recursos denuestras
aplicaciones. Estos recursos los gestiona el Internet Information
Server (IIS) deMicrosoft, por lo que la seguridad en ASP.NET es un
aspecto ms relacionado con la correctaconfiguracin del servidor web
que con la programacin de la aplicacin en s.
Sin entrar en demasiados detalles (que seguro son de inters para
los aficionados a lastcnicas criptogrficas de proteccin de datos),
en las siguientes pginas veremos cmo sepueden implementar
mecanismos de identificacin de usuarios a travs de contraseas
paracontrolar el acceso a aplicaciones web desarrolladas con pginas
ASP.NET. Posteriormente,comentaremos cmo podemos controlar las
acciones que el usuario puede realizar en elservidor, para terminar
con una breve descripcin del uso de transmisiones seguras en la
Web.
Autentificacin y autorizacinCuando queremos controlar el acceso
a una aplicacin web, lo normal es que el usuario seidentifique de
alguna forma. Por regla general, esta identificacin se realiza
utilizando unnombre de usuario nico y una contrasea que el usuario
ha de mantener secreta. En laaplicacin web, esto se traduce en que
el usuario es automticamente redirigido a unformulario de login
cuando intenta acceder a un rea restringida de la aplicacin.
En el fichero de configuracin Web.config, que ya ha aparecido
mencionado en variasocasiones a lo largo de este captulo, se
incluyen dos secciones relacionadas directamente conla
autentificacin y la autorizacin de usuarios. Su aspecto en una
aplicacin real suele sersimilar al siguiente:
111Aplicaciones web
http://csharp.ikor.org/
-
La autentificacin consiste en establecer la identidad de la
persona que intenta acceder a laaplicacin, lo que se suele realizar
a travs de un formulario de login. La autorizacin consisteen
determinar si el usuario, ya identificado, tiene permiso para
acceder a un determinadorecurso.
AutentificacinLa seccin de autentificacin del fichero
Web.config, delimitada por la etiqueta, se utiliza para establecer
la poltica de identificacin de usuarios queutilizar nuestra
aplicacin. ASP.NET permite emplear distintos modos de
autentificacin,entre los que se encuentran los siguientes:
- Forms se emplea para utilizar formularios de autentificacin en
los que seremosnosotros los que decidamos quin accede a nuestra
aplicacin.
- Passport permite que nuestra aplicacin utilice el sistema de
autentificacinPassport de Microsoft (ms informacin en
http://www.passport.com).
- Windows se utiliza para delegar en el sistema operativo las
tareas deautentificacin de usuarios, con lo cual slo podrn acceder
a nuestra aplicacinlos usuarios que existan previamente en nuestro
sistema (por ejemplo, los usuariosde un dominio).
- Finalmente, None deshabilita los mecanismos de autentificacin,
con lo quecualquiera puede acceder a ella desde cualquier lugar del
mundo sin restriccinalguna.
Cuando seleccionamos el modo de autentificacin Forms, hemos de
indicar tambin culser el formulario encargado de identificar a los
usuarios de la aplicacin. En el ejemploanterior, ese formulario es
login.aspx. Un poco ms adelante veremos cmo se puedecrear dicho
formulario.
112 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
AutorizacinDespus de la seccin de autentificacin, en el fichero
Web.config aparece la seccin deautorizacin, delimitada por la
etiqueta . En el ejemplo anterior, estaseccin se utiliza,
simplemente, para restringir el acceso a los usuarios no
identificados, deforma que slo los usuarios autentificados puedan
usar la aplicacin web.
Las secciones de autentificacin y autorizacin del fichero
Web.config restringen elacceso a un directorio y a todos sus
subdirectorios en la aplicacin web. No obstante, en
lossubdirectorios se pueden incluir otros ficheros Web.config que
redefinan las restriccionesde acceso a los subdirectorios de
nuestra aplicacin web. Piense, si no, que sera necesaria
unaaplicacin web independiente para permitir que usuarios nuevos se
registrasen en nuestraaplicacin web.
Por ejemplo, si en una parte de nuestra aplicacin queremos que
cualquier persona puedaacceder, incluso sin identificarse, basta
con incluir la siguiente autorizacin en el fichero deconfiguracin
adecuado:
Esto nos permite tener aplicaciones en las que haya partes
pblicas y partes privadas, comosucede en cualquier aplicacin de
comercio electrnico. En ellas, los usuarios pueden
navegarlibremente por el catlogo de productos ofertados pero han de
identificarse al efectuar suscompras.
Si lo que quisiramos es restringir el acceso a usuarios o grupos
de usuarios particulares,podemos hacerlo incluyendo una seccin de
autorizacin similar a la siguiente en nuestrofichero
Web.config:
113Aplicaciones web
http://csharp.ikor.org/
-
Autentificacin en WindowsUna vez visto cmo podemos controlar qu
usuarios acceden a qu partes de la aplicacin,volvamos ahora al
problema inicial: cmo identificar a los usuarios en un primer
momento?.
Una de las alternativas que nos ofrece ASP.NET es utilizar el
sistema operativo Windowscomo mecanismo de autentificacin. Es
decir, los nombres de usuario y las claves de accesopara nuestra
aplicacin web sern los mismos nombres de usuarios y claves que se
utilizanpara acceder a nuestros ordenadores.
Para utilizar este mecanismo de autentificacin, debemos
especificar Windows como modode autentificacin en el fichero
Web.config. Adems, deberemos eliminar el accesoannimo a nuestra
aplicacin desde el exterior. Para lograrlo, hemos de cambiar
laspropiedades del directorio de nuestra aplicacin en el Internet
Information Server:
Una vez dentro de las propiedades relacionadas con el control de
"autenticacin" y accesoannimo, deshabilitamos el acceso annimo:
114 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
Una vez realizadas las modificaciones pertinentes en las
secciones de autentificacin yautorizacin del fichero Web.config y
deshabilitado el acceso annimo al directorio denuestra aplicacin,
cuando intentamos acceder a la aplicacin nos debe aparece una
ventanacomo la siguiente:
Esta ventana nos pide que introduzcamos un nombre de usuario y
su contrasea. El nombre deusuario ha de existir en nuestro sistema
operativo y la contrasea ha de ser la misma que
115Aplicaciones web
http://csharp.ikor.org/
-
utilizamos para acceder al ordenador. Si tras varios intentos no
somos capaces de introducirun nombre de usuario vlido y su
contrasea correspondiente, el servidor web nos devolverun error de
autentificacin "HTTP 401.3 - Access denied by ACL onresource":
Este error de autentificacin, "acceso denegado por lista de
control de acceso", se debe a queel nombre de usuario introducido
no est incluido en la lista de usuarios que estn
autorizadosexpresamente para acceder a la aplicacin web, a los
cuales deberemos incluir en la seccinauthorization del fichero de
configuracin Web.config.
Formularios de autentificacin en ASP.NETEn determinadas
ocasiones, no nos podremos permitir el lujo de crear un usuario en
el sistemaoperativo para cada usuario que deba acceder a nuestra
aplicacin. Es ms, posiblemente nonos interese hacerlo.
Probablemente deseemos ser nosotros los encargados de gestionar
losusuarios de nuestra aplicacin y controlar el acceso de stos a
las distintas partes de nuestrosistema.
El modo de autentificacin Forms es el ms indicado en esta
situacin. Para poder utilizarlo,debemos configurar correctamente el
fichero Web.config, tal como se muestra acontinuacin:
116 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
Cuando un usuario no identificado intente acceder a una pgina
cuyo acceso requiera suidentificacin, lo que haremos ser
redirigirlo a un formulario especfico de login,Login.aspx. Dicho
formulario, al menos, debe incluir dos campos para que el
usuariopueda indicar su nombre y su clave:
El formulario de identificacin incluir, por tanto, dos controles
de tipo TextBox. Dado quela contrasea del usuario ha de mantenerse
secreta, en el TextBox correspondiente a la clavede acceso se ha de
especificar la propiedad TextMode=Password. El formulario, en s,
locrearemos igual que cualquier otro formulario. Lo nico que
tendremos que hacer escomprobar nombre y contrasea. Esta
comprobacin se ha de realizar de la siguiente forma:
if ( textBoxID.Text.Equals("usuario")&&
textBoxPassword.Text.Equals("clave") ) {
FormsAuthentication.RedirectFromLoginPage(textBoxID.Text,false);
} else {
// Error de autentificacin...}
Cuando un usuario no identificado intenta acceder a cualquiera
de los formularios de nuestraaplicacin, el usuario es redirigido al
formulario de identificacin:
117Aplicaciones web
http://csharp.ikor.org/
-
Una vez que el usuario se identifica correctamente, la llamada
al mtodoRedirectFromLoginPage le indica al IIS que debe darle
permiso al usuario para accedera la pgina a la que inicialmente
intent llegar. Este mtodo pertenece a la claseFormsAuthentication,
la cual est incluida en el espacio de nombresSystem.Web.Security.
El IIS se encargar de todo lo dems por nosotros y mandar alusuario
a la pgina adecuada:
Slo cuando nos identifiquemos correctamente deberamos poder
acceder ala aplicacin.
118 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
Si el usuario no se identifica correctamente, ya sea porque no
est dado de alta o porque nohaya introducido correctamente su clave
de acceso, se debe mostrar un mensaje informativode error:
Obviamente, en una aplicacin real no deberamos ser tan
explcitos. Cuando el usuario seequivoque en su clave de acceso o su
identificador no exista en nuestra base de datos deusuarios
registrados, el mensaje de error se le puede mostrar utilizando una
etiqueta(labelMessage.Text=...), tal y como acabamos de hacer.
Tambin podemos redirigiral usuario a otra pgina mediante
Response.Redirect("http://...");. Estoltimo suele ser lo ms
adecuado si nuestro sistema permite que nuevos usuarios se den
dealta ellos mismos.
Permisos en el servidorLas aplicaciones ASP.NET no suelen
residir en un mundo aislado, sino que suelen interactuarcon otras
aplicaciones y acceder a distintas bases de datos y ficheros.
El proceso que se encarga de ejecutar las pginas ASP.NET
(aspnet_wp.exe) se ejecutautilizando una cuenta de usuario llamada
ASPNET. Por tanto, si una pgina ASP.NET ha deacceder a un recurso
concreto, se le han de dar los permisos adecuados al usuario
ASPNET.Por ejemplo, si la aplicacin web ha de escribir datos en un
fichero concreto, el usuarioASPNET ha de tener permiso de escritura
sobre dicho fichero.
119Aplicaciones web
http://csharp.ikor.org/
-
Este modelo de seguridad es bastante sencillo y simplifica
bastante el trabajo deladministrador del sistema, ya que slo ha de
incluir al usuario ASPNET en las listas de controlde acceso de los
recursos a los que las aplicaciones web deban tener acceso. Esto
es,independientemente de los usuarios que luego utilicen la
aplicacin, el administrador notendr que ir dndole permisos a cada
uno de esos usuarios. Adems, este modelo tiene otrasimplicaciones
relacionadas con la eficiencia de las aplicaciones web. Si se han
de establecerconexiones con una base de datos, todas las conexiones
las realiza el mismo usuario, por loque se puede emplear un pool de
conexiones, el cual permite compartir recursos de formaeficiente
entre varios usuarios de la aplicacin (con la consiguiente mejora
en suescalabilidad).Para que las acciones de la aplicacin web se
realicen con los privilegios del usuarioASPNET, debemos asegurarnos
de que el fichero de configuracin Web.config incluye lasiguiente
lnea:
Otra alternativa, disponible cuando la aplicacin ASP.NET utiliza
el modo de autentificacinWindows, consiste en utilizar las
credenciales de los usuarios de la aplicacin. En este caso,el
administrador del sistema deber dar los permisos necesarios a cada
uno de los usuariosfinales de la aplicacin. Aunque resulte ms
"incmoda" su labor, esta opcin es ms flexible,ya que permite
auditar las acciones que realiza cada usuario y evita los problemas
deseguridad que podran surgir si el servidor web se viese
comprometido. Para que nuestraaplicacin web funcione segn este
modelo de seguridad, el fichero Web.config deberincluir las
siguientes lneas:
...
En cualquiera de los dos modelos de seguridad comentados,
siempre se debe aplicar el"principio de menor privilegio": darle el
menor nmero posible de permisos a los usuarios delsistema y
ocultarles las partes de la aplicacin responsables de realizar
tareas para las que notengan autorizacin. Adems, dado el entorno
potencialmente hostil en el que ha de funcionaruna aplicacin web,
la interfaz externa de la aplicacin ha de ser especialmente
cuidadosa a lahora de permitir la realizacin de cualquier tipo de
accin y no realizar ninguna suposicin.Toda entidad externa ha de
considerarse insegura, por lo que cualquier entrada ha de
validarseexhaustivamente antes de procesarse.
120 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
-
Seguridad en la transmisin de datosLos apartados anteriores han
descrito cmo podemos controlar el acceso a las distintas partesde
una aplicacin y cmo podemos establecer permisos que impidan que un
usuario realiceacciones para las que no tiene autorizacin (ya sea
malintencionadamente o, simplemente, porerror). No obstante, no
hemos dicho nada acerca de otro aspecto esencial a la hora
deconstruir aplicaciones seguras: el uso de tcnicas criptogrficas
de proteccin de datos queprotejan los datos que se transmiten entre
el cliente y el servidor durante la ejecucin de unaaplicacin
web.
Para estos menesteres, siempre se deben utilizadas soluciones
basadas en algoritmos cuyaseguridad haya sido demostrada, los
cuales suelen tener una base matemtica que garantiza
suinviolabilidad usando la tecnologa actual. De hecho, no es una
buena idea crear tcnicas amedida para nuestras aplicaciones. Aparte
de que su diseo nos distraera del objetivoprincipal de nuestro
proyecto (entregar, en un tiempo razonable, la funcionalidad que
elcliente requiera), no conviene mezclar los detalles de una
aplicacin con aspectos ortogonalescomo puede ser el uso de tcnicas
seguras de transmisin de datos. Estas tcnicas son las quenos
permiten garantizar la privacidad y la integridad de los datos
transmitidos. Su uso resultaindispensable, y puede que legalmente
obligatorio, cuando nuestra aplicacin ha de trabajarcon datos
"sensibles", tales como nmeros de tarjetas de crdito o historiales
mdicos.En el caso concreto de las aplicaciones web, que en el
cliente se suelen ejecutar desdenavegadores web estndar, lo normal
es usar la infraestructura que protocolos como HTTPSnos ofrece. El
protocolo HTTPS, un HTTP seguro, est basado en el uso de SSL
[SecureSockets Layer], un estndar que permite la transmisin segura
de datos. El protocolo HTTPmanda los datos tal cual, sin encriptar,
por lo que cualquier persona que tenga una conexin acualquiera de
las redes por donde se transmiten los datos desde el cliente hasta
el servidorpodra leerlos. HTTPS nos permite proteger los datos que
se transmiten entre el cliente y elservidor. Para utilizar este
protocolo, lo nico que debemos hacer es instalar un certificado
enel IIS.
HTTPS utiliza tcnicas criptogrficas de clave pblica para
proteger los datos transmitidos yque slo el destinatario pueda
leerlos. Estas tcnicas consisten en utilizar pares de
clavesemitidas por autoridades de certificacin. Estos pares estn
formados por una clave pblica yuna clave privada, de tal forma que
lo codificado con la clave pblica slo puede leerse si sedispone de
la clave privada y viceversa. Si queremos que slo el destinatario
sea capaz de leerlos datos que le enviamos, lo nico que tenemos que
hacer es codificarlos utilizando su clavepblica. Como slo l dispone
de su clave privada, slo l podr leer los datos que le
hayamosenviado. El certificado que hemos de instalar en el IIS no
es ms que un par clave pblica -clave privada emitido por alguna
entidad, usualmente externa para evitar que alguien puedasuplantar
al servidor.
Aparte de las tcnicas criptogrficas que impiden que los datos se
puedan leer, HTTPStambin aade a cada mensaje un cdigo de
autentificacin HMAC (Keyed-Hashing for
121Aplicaciones web
http://csharp.ikor.org/
-
Message Authentication, RFC 2104). Este cdigo sirve para que, al
recibir los datos, podamosgarantizar su integridad. Si alguien
manipula el mensaje durante su transmisin, el cdigoHMAC no
corresponder al mensaje recibido.El uso de estndares como HTTPS
permite que nuestras aplicaciones web puedan emplearmecanismos
seguros de comunicacin de forma transparente. Lo nico que tendremos
quehacer es configurar adecuadamente nuestro servidor web y hacer
que el usuario acceda anuestras aplicaciones web utilizando URLs de
la forma https://.... Slo en casos muypuntuales tendremos que
preocuparnos directamente de aspectos relacionados con latransmisin
segura de datos. Y no ser en nuestras interfaces web, que de eso ya
se encarga elIIS.
HTTPS no es la nica opcin disponible para garantizar
latransmisin segura de datos, aunque s la ms usada. existeuna
variante del protocolo IP usado en Internet, conocidocomo IPSec,
que permite aadir cabeceras de autentificacina los datagramas IP,
adems de encriptar el contenido delmensaje. Este protocolo,
utilizado en "modo tnel", permite lacreacin de redes privadas
virtuales (VPNs). Estas redes sonmuy tiles cuando una organizacin
tiene varias sedes quehan de acceder a sistemas de informacin
internos. Las VPNspermiten que varias redes separadas
geogrficamentefuncionen como si de una nica red de rea local se
tratase.Para ello, pueden alquilar lneas privadas a empresas
detelecomunicaciones (como los cajeros automticos de losbancos) o
establecer conexiones seguras a travs de Internetentre las
distintas redes fsicas ("tneles").
122 Desarrollo Profesional de Aplicaciones con C#
Fernando Berzal, Francisco J. Cortijo & Juan Carlos
Cubero
El protocolo HTTPEn el camino correctoControl del trfico con
manejadores y filtros HTTPCuestin de refrescoAlmacenamiento en
cachEn el navegador web del cliente...... y en el servidor web
Cookies
Sesiones de usuario en ASP.NETEl contexto de una pgina
ASP.NETMantenimiento del estado de una aplicacin web
Seguridad en ASP.NETAutentificacin y autorizacinAutentificacin
en WindowsFormularios de autentificacin en ASP.NETPermisos en el
servidorSeguridad en la transmisin de datos