Software Versioning

Every day, we cope with software versioning.

We often hear sentences like: “Hey, have you seen the new Firebug 1.3.3?”, “Have you installed Ubuntu 8.10?”, “When will Windows 7 be released?”, “Is Gmail still in Beta?” or “Check my new web 2.0 site!”

Personally, and it seems that a lot of people agree about this, I like the Ubuntu versioning pattern: the major version indicates the year of releasing, and the minor one the year’s month when it was released.

If we talk about web applications, I prefer putting the revision number of the published revision in our source control in some hidden place, so if the application is hosted in different servers is easy to know what version of the software is our server running. (Note: check the downsides: if it’s a very public project, you are making cracker’s life easier)

It’s a reality that there aren’t any standards for software versioning and naming, and frequently development teams and marketing folks use different names for the same version of a product. As always, life will be easier if we had some standards in place.

But the way, we have some de facto conventions, and we should use them. If we use the popular X.Y.Z versioning format, a change in X implies massive architecture changes, and a change in Y means that there exists compatibility with other versions with same X.

If you are using .NET Framework, you should know that you can generate your assemblies version automatically based on the time of compilation. Check the article about AssemblyVersionAttribute from the MSDN:

When specifying a version, you have to at least specify major. If you specify major and minor, you can specify an asterisk (*) for build. This will cause build to be equal to the number of days since January 1, 2000 local time, and for revision to be equal to the number of seconds since midnight local time, divided by 2.
If you specify major, minor, and build, you can specify an asterisk for revision. This will cause revision to be equal to the number of seconds since midnight local time, divided by 2.

This article came to my mind when I read about the new PHP release, PHP 5.3. The previous was only some context for my rant:

What were PHP people thinking about when they decided changing only the minor version number with a new version with backward-compatibility issues?

If you are going to feel the pain, maybe this IBM post series can ease you: What’s new in PHP V5.3.

PS: They’ve introduced goto in the language too. I won’t say anything about it. Use it at your own risk.

Leyendo el tebeo, también por la noche…

Como mañana tengo examen, me siento con fuerzas y el tiempo disponible para rebatir con más profundidad el artículo anterior, y a mis queridos comentaristas.

En primer lugar, voy a ir desmenuzando el fragmento anterior:

¿Y qué decir pues de los clubes .net que Microsoft alienta en las universidades? Clubes con los que propicia el uso de sus anti-estándares y que los alumnos aprendan a programar de forma incompatible con el resto.

En primer lugar, más que Microsoft buscar a los alumnos fueron/son los alumnos los que busca(ro)n a Microsoft. Ese “aliento”, que bien podrían dar otras compañías (y me consta que a otras compañías se les ofreció algo similar a los clubs .net, sin pedir nada a cambio, y se negaron), se materializa exclusivamente a través de libros y documentación, así como de hardware en el que “trastear”.

En cuanto al uso de anti-estándares… Desconozco “esa cosa”. Una cosa (protocolo, formato, etc) o es estándar o no lo es, pero no puede ser “antiestándar”. Esto muestra, por un lado, el grado de conocimiento y rigurosidad del autor del texto; por otro, su “propósito de contar la verdad absoluta”. El que quiera tener los ojos abiertos, que busque en ISO, ECMA o IEEE la participación de Microsoft, o los artículos en Port25 sobre el trabajo en sus laboratorios en busca de la compatibilidad.

En lo de “programar de forma incompatible” ni me voy a meter. Quizá se refiera al uso de metodologías como el SDLC. Desconozco que es “programar de forma incompatible”, aunque estimo que será hacer webs en php que no se integren con aplicaciones python.

A Microsoft le interesa que sea incompatible para que cuando acaben la carrera no puedan desligarse de las herramientas del monopolio y obliguen a sus clientes y usuarios a caer en el mismo problema. Y tan metidos están dentro, que ven imposible la solución y, en vez de reconocer el problema, se convierte en un punto ciego donde no quieren mirar. Prefieren confiar en el Monopolio mientras hacen caer a más gente en la trampa de licencias de uso regaladas de entornos de desarrollo y de Windows como un camello que regala la droga inicialmente esperando que se enganchen.

Aquí se atisba algo de lucidez. Evidentemente, a Microsoft le benefician estos grupos de usuarios. ¿Gente que ofrezca soporte, documentación, charlas y demás de manera gratuita? Perfecto. No debería sorprender a un miembro de un grupo de usuarios que existan otros grupos de usuarios.

En cuanto a obligar a clientes y usuarios a “caer” en Windows… en mi mundo existen dos tipos de desarrollos informáticos: o servicios a medida, o productos. En el primer caso los requisitos los pone el cliente. En el segundo, desarrollo mi producto como me da la gana y tú si te interesa lo compras, nadie te obliga. Más simple imposible.

Por otro lado, los grupos de usuarios no son sectas. Nada te impide “mirar hacia el otro lado”, e incluso tocar. Una tecnología no es una novia a la que debas fidelidad, es una relación liberal.

¿Cómo evaluar el coste económico de que se margine a la gente del saber?

Y digo yo… ¿Dónde está mi libertad para aprender lo que me parezca sin que nadie critique mi elección?

Desarrollo con tecnologías de Microsoft, desarrollo con tecnologías de otras empresas, desarrollo con tecnologías libres… y desarrollo y colaboro con proyectos libres. Creo que queda bastante claro mi posición en el debate Torvalds vs Stallman, yo estoy del lado del primero, esto no es una religión.

Pero entre todos estos y mis necesidades, me quedo con satisfacer las últimas.

Leyendo el tebeo…

Ojeando muy por encima el tebeo (si lo lees de verdad eres capaz de creértelo) me encuentro:

¿Y qué decir pues de los clubes .net que Microsoft alienta en las universidades? Clubes con los que propicia el uso de sus anti-estándares y que los alumnos aprendan a programar de forma incompatible con el resto. A Microsoft le interesa que sea incompatible para que cuando acaben la carrera no puedan desligarse de las herramientas del monopolio y obliguen a sus clientes y usuarios a caer en el mismo problema. Y tan metidos están dentro, que ven imposible la solución y, en vez de reconocer el problema, se convierte en un punto ciego donde no quieren mirar. Prefieren confiar en el Monopolio mientras hacen caer a más gente en la trampa de licencias de uso regaladas de entornos de desarrollo y de Windows como un camello que regala la droga inicialmente esperando que se enganchen.

¿Cómo evaluar el coste económico de que se margine a la gente del saber?

¿No es irónica la pregunta final?

ASP.NET: Getting the absolute url of a web page

Recently, I needed the way of getting the absolute URL of a web page in ASP.NET. With absolute URL, I mean the url what clients have to point to their browsers (this URL will be sent by mail), not the absolute URL relative to the web app, like the ASP.NET API seems to understand ‘absolute’.

I thought that there would be some method in the .NET Framework, but if it exists, I missed it. I looked at System.Web.VirtualPathUtility, System.IO.Path, System.Web.UI.Page and System.Web.HttpServerUtility, but no luck.

So I had to implement this. It is only a line of code, but I think that this can be useful for anyone else (including Future Me).

           String url = new Uri(Context.Request.Url, 
                            ResolveUrl("~/Example.aspx")).ToString();

If you’re using the development server Cassini, included with Visual Studio, it will return something similar to http://localhost:1234/Example.aspx. In production on IIS, it will return something like http://example.com/Example.aspx.

If you know a better way of getting the absolute URL from a page, feel free to leave a comment.

Los 5 errores más comunes en servicios web ASP.NET

Traducción del artículo publicado por Paul Ballard el 27 de mayo de 2005 en TheServerSide.NET. Además de la traducción inglés-castellano, he traducido los ejemplos de VB.NET a C#. Puedes encontrar el original aquí: Top 5 Web Service mistakes.

En este artículo vamos a comentar los 5 errores más comunes que comenten las empresas cuando desarrollan servicios web en .NET. Es importante resaltar que no son errores de lógica o sintaxis. No hay errores de compilación que te digan que algo está mal y no se lanzarán excepciones. Son problemas de arquitectura, no de tecnología. La clave, por tanto, es evitarlos desde el principio, ya que intentar corregirlos después de su puesta en producción puede ser mucho más complicado.

1. Usando tipos específicos de .NET.

El concepto fundamental detrás de los servicios web es la creación de lógica de aplicación accesible en cualquier momento, desde cualquier sitio, por cualquier otra aplicación independientemente de la tecnología. Esto incluye también a aplicaciones no .NET. El aspecto más importante para garantizar la interoperabilidad en servicios web no se encuentra en el código, o al menos no directamente. Para que un servicio sea interoperable con cualquier tecnología el contrato de datos que define debe estar basado en tipos definidos en un XML Schema, no en el framework .NET. Por tanto, si usas tipos específicos de .NET como parámetros o valores de retorno para un servicio web, el XML que produce puede no ser interoperable con Java u otra tecnología.

Quizá has visto las demos de cómo de fácil es crear un simple servicio web que consulta a una base de datos y devuelve los datos como un Dataset de ADO.NET. Un Dataset es una versión totalmente desconectada de datos relacionales, incluyendo tablas, claves, y relaciones y demás, por lo que puede parecer el objeto perfecto para transmitir datos entre distintas localizaciones. En el caso de los servicios web, las apariencias engañan.

Pasar un Dataset como resultado o parámetro en un servicio web crea distintos problemas. El primero ocurre en el WSDL. WSDL es el schema XML que define como los clientes pueden interactuar con tu servicio y qué parametros y valores de retorno utiliza. WSDL es a menudo utilizado para generar clases proxy del lado del cliente, por lo que mientras más descriptivo sea, más fácil será interactuar con nuestro servicio.

Veamos un ejemplo de un simple servicio con un método que devuelve un Dataset que contiene un fila de la tabla Customers de la base de datos Northwind. A continuación se muestra el WSDL para ese servicio. Fíjate en la elemento GetCustomersResponse.

<s:element name=GetCustomersResponse>

  <s:complexType>

    <s:sequence>

      <s:element minOccurs=0 maxOccurs=1 name=GetCustomersResult>

        <s:complexType>

          <s:sequence>

            <s:element ref=s:schema/>

            <s:any/>

          </s:sequence>

        </s:complexType>

      </s:element>

    </s:sequence>

  </s:complexType>

</s:element>

Debido a que la estructura del Dataset no se conoce hasta tiempo de ejecución, no hay manera para el WSDL de describir su estructura interna. Para resolver esto, el valor de retorno (elemento GetCustomersResponse) del método GetCustomers tiene dos elementos, un elemento de tipo any (<s:any/>) que es en efecto un tipo de objeto y un XML Schema (<s:schema>) que en tiempo de ejecución describirá la estructura del Dataset de retorno. Esto es el equivalente en servicios web a late binding.

Debido a que el desarrollador del cliente no sabe la estructura del objeto que tu método devolverá, no podrán generar un proxy muy útil. Podrán usar tu servicio web, pero deberán parsear el XML de retorno para encontrar los datos que están buscando. La seguridad de tipos se ha tirado por el retrete y has hecho que el trabajo de cualquier desarrollador de un cliente no .NET sea más difícil.

Ahora deberías estar diciéndote a tí mismo: “Si el WSDL no define un tipo de retorno Dataset, ¿cómo funcionan todas esas demos?”. La respuesta está en el XML devuelto en tiempo de ejecución. A continuación se muestra el resultado de llamar a nuestro método GetCustomers.

<?xml version=1.0 encoding=utf-8?>

<DataSet xmlns=http://tempuri.org/>

  <xs:schema id=NewDataSet xmlns=“” xmlns:xs=http://www.w3.org/2001/XMLSchema xmlns:msdata=urn:schemas-microsoft-com:xml-msdata>

    <xs:element name=NewDataSet msdata:IsDataSet=true msdata:UseCurrentLocale=true>

      <xs:complexType>

        <xs:choice minOccurs=0 maxOccurs=unbounded>

          <xs:element name=Table>

            <xs:complexType>

              <xs:sequence>

                <xs:element name=CustomerID type=xs:string minOccurs=0 />

 

                <xs:element name=CompanyName type=xs:string minOccurs=0 />

                <xs:element name=ContactName type=xs:string minOccurs=0 />

                <xs:element name=ContactTitle type=xs:string minOccurs=0 />

                <xs:element name=Address type=xs:string minOccurs=0 />

                <xs:element name=City type=xs:string minOccurs=0 />

                <xs:element name=Region type=xs:string minOccurs=0 />

                <xs:element name=PostalCode type=xs:string minOccurs=0 />

                <xs:element name=Country type=xs:string minOccurs=0 />

                <xs:element name=Phone type=xs:string minOccurs=0 />

 

                <xs:element name=Fax type=xs:string minOccurs=0 />

              </xs:sequence>

            </xs:complexType>

          </xs:element>

        </xs:choice>

      </xs:complexType>

    </xs:element>

  </xs:schema>

  <diffgr:diffgram xmlns:msdata=urn:schemas-microsoft-com:xml-msdata xmlns:diffgr=urn:schemas-microsoft-com:xml-diffgram-v1>

 

    <NewDataSet xmlns=“”>

      <Table diffgr:id=Table1 msdata:rowOrder=0>

        <CustomerID>ALFKI</CustomerID>

        <CompanyName>Alfreds Futterkiste</CompanyName>

        <ContactName>Maria Anders</ContactName>

        <ContactTitle>Sales Representative</ContactTitle>

        <Address>Obere Str. 57</Address>

 

        <City>Berlin</City>

        <PostalCode>12209</PostalCode>

        <Country>Germany</Country>

        <Phone>030-0074321</Phone>

        <Fax>030-0076545</Fax>

      </Table>

 

    </NewDataSet>

  </diffgr:diffgram>

</DataSet>

Fíjate en que el elemento NewDataSet tiene un atributo específico de Microsoft llamado “IsDataSet”. Esta es una pista de Visual Studio de que el resultado debería ser deserializado como Dataset. Por supuesto, esto no significa nada si estás llamando a este servicio web desde un cliente no .NET como J2EE.

El segundo problema cuando pasamos Datasets a y desde un servicio web es la gran cantidad de datos que se envía. El XML que vimos anteriormente sólo describe la estructura de un dataset con una tabla. Mientras añades tablas, relaciones y claves, el schema se vuelve más complejo y más grande. De hecho, rápidamente puede convertirse en mayor que los datos que se devuelven. Recuerda, mientras más datos envíes a / desde un servicio más lenta se volverá la petición.

El Dataset es probablemente la forma más común de usar tipos específicos de .NET en servicios web pero no es el único caso. Tiene mucho sentido para un desarrollador .NET querer usar las características avanzadas y las clases provistas por el framework .NET. Sin embargo, si la interoperabilidad real es tu objetivo, tendrás que controlar tus impulsos. Para interoperabilidad máxima, la clave es asegurarse que todos los tipos que se utilizan como parámetros y valores de retorno pueden describirse usando los tipos básicos del XML Schema estándar. Puedes encontrar la definición de todos esos tipos en http://www.w3.org/TR/xmlschema-2/

2. No aprovecharse de ASP.NET

La mayor desventaja de consumir servicios web es el rendimiento. Cualquier mejora que se pueda realizar para incrementar el rendimiento merece el esfuerzo. Los servicios web desarrollados en .NET se despliegan en ASP.NET y por tanto puedes acceder a todas esas grandes características de cualquier aplicación web ASP.NET. Para el rendimiento, las características más importantes son el Caching y el SessionState.

Los servicios web pueden usar dos tipos de cacheo. El primero y el más sencillo es cacheo de salida. El cacheo de salida permite que el resultado de un servicio web se almacene en la caché del servidor. Las siguientes peticiones a ese método que usen los mismos parámetros obtendrán los valores cacheados en el servidor sin llamar al método del servicio y por tanto, sin consulta de datos, lógica, etc. Cuando los parámetros del método cambian se añade una entrada a la caché del servidor con el tiempo de expiración especificado. Para usar esta característica, sólo añade la propiedad “CacheDuration” a la clase WebMethodAttribute. Aquí hay un ejemplo simple que cachea el resultado de un método durante 120 segundos.

        [WebMethod(CacheDuration=120)]

        public Quote GetQuote ()

También puedes usar el cacheo de datos de aplicación para almacenar datos específicos entre peticiones. Datos que se utilizan a menudo pero que no cambian tan frecuentemente son los primeros candidatos a ser almacenados en la caché de la aplicación.

Para ilustrar esto vamos a construir un servicio ficticio para obtener cotizaciones de acciones. Una función que ofrece este servicio es la posibilidad de obtener el símbolo de una empresa utilizando su nombre. Una función como ésta debe ser llamada a menudo, a pesar de que los cambios en los datos apenas varían. En este caso querremos consultar la base de datos una vez al inicio y devolver un array conteniendo todos los nombres de empresas y sus correspondientes símbolos y almacenar ese array en la caché con una expiración diaria. Cuando un cliente busca el símbolo de una empresa, en vez de hacer una llamada a la base de datos con cada petición podemos buscarla en el array almacenado en caché. A continuación se muestra el código necesario para implementar este tipo de cacheo.

        [WebMethod]

        public Symbol[] GetAllSymbols ()

        {

            Symbol [] symbols;

            if (HttpContext.Current.Cache [“AllSymbols”] == null)

            {

                symbols = _QuotesData.GetAllSymbols(); // extrae datos de la BBDD

                HttpContext.Current.Cache.Add(“AllSymbols”, symbols, null, DateTime.MaxValue,

                    new TimeSpan(24, 0, 0), System.Web.Caching.CacheItemPriority.Normal, null);

            }

            else

            {

                symbols = HttpContext.Current.Cache [“AllSymbols”] as Symbol[];

            }

            return symbols;

        }

Los servicios web también pueden usar la persistencia en el estado de la sesión ofrecida a través de ASP.NET incluyendo estado fuera del proceso del servidor y SQL Server. Para habilitar esta característica añade “EnableSession=True” al atributo WebMethod. Esto es muy útil para almacenar información específica del cliente entre peticiones. Por ejemplo, continuando el desarrollo de nuestro sistema de análisis de stock vamos a decir que nuestro servicio web permite a los clientes crear una lista personalizada de stocks que están siguiendo. Cuando el cliente solicita la lista de stocks para ese usuario la primera vez, almacenamos la lista en la sesión antes de devolverlo al cliente. Ahora podemos modificar nuestro método para obtener la lista de los stocks desde el SessionState si el cliente no ha mandado una nueva lista. Esto puede aumentar el rendimiento de las actualizaciones sustancialmente. La siguiente figura muestra ejemplos de métodos que utilizan el estado de la sesión.

        [WebMethod(CacheDuration = 60, EnableSession = true)]

        public Quote [] GetQuotes (string [] symbols)

        {

            List<Quote> lQuotes = new List<Quote>();

            foreach (string symbol in symbols)

            {

                lQuotes.Add(GetQuote(symbol));

            }

            // Store in SessionState just in case the client wants to recall without

            // sending the list again

            HttpContext.Current.Session [“SymbolList”] = symbols;

            return lQuotes.ToArray();

        }

 

        [WebMethod(CacheDuration = 60, EnableSession = true)]

        public Quote [] GetQuotesFromSession ()

        {

            string [] symbols = (string[]) HttpContext.Current.Session [“SymbolList”];

            return GetQuotes(symbols);

        }

ASP.NET utiliza cookies en el cliente para identificar de manera única cada sesión, por tanto, para utilizar esta característica, necesitarás cierto trabajo en el cliente. Con .NET es muy simple, sólo necesitamos crear un nuevo CookieContainer para almacenar las cookies recibidas desde el servicio. Aquí está el código de cliente necesario para hacer esto:

            myService.CookieContainer = new System.Net.CookieContainer();

Aunque usar el estado de la sesión puede aumentar el rendimiento, “rompe” las reglas de la orientación a servicios atendiendo a que los servicios no deben tener estado. Es muy importante recordar también que no todos los clientes son capaces de aceptar tus cookies. La mejora de rendimiento es sustancial y con algunas advertencias, creo que merece la pena usarlo.

Advertencia 1: Cualquier método web que use el estado de la sesión debe tener su correspondiente versión sin estado.

Advertencia 2: Por claridad, debes nombrar a tus métodos con estado de modo que el desarrollador del cliente sepa que el uso del estado de la sesión está habilitado.

3. Not Enough Bang for the Buck

Si tú personalmente tuvieras que seguir a pie el camino que las peticiones a tu servicio web hacen a través de la compañía o a través del mundo, una cosa es cierta: querrías hacer el viaje sólo una vez. Esta es la misma razón por la que hacemos una lista antes de ir al supermercado en vez de hacer el viaje para cada producto. Hay siempre una disminución de rendimiento o un aumento del tráfico de red con cada petición.

Tus servicios web deberían diseñarse para maximizar la cantidad de trabajo que se realiza con cada petición. Asegúrate de que la funcionalidad que estás ofreciendo a través del servicio valga el tiempo y el esfuerzo que el cliente gastó en hacerte la petición. Como ejemplo, vamos a trabajar en nuestro servicio de cotizaciones.

Probablemente has visto demos que muestran lo sencillo que es enviar un símbolo y recibir una cotización actual de mercado. Pero ¿y si quieres conocer el precio de 10 símbolos a la vez? Usando la versión de la demo, deberías hacer diez peticiones al servidor. ¿Querrías dar esa caminata?

Para mejor rendimiento, considera combinar esas pequeñas peticiones en una única petición mayor. En el caso de los precios de las acciones, es sencillo combinar los símbolos de entrada en un array de cadenas y devolver un array de Quotes en el método. Esta implementación del método GetQuotes se puede ver en el fragmento de código anterior.

En casos más complejos, tus servicios pueden comenzar a asemejarse al patrón Request-Broker y de hecho muchos servicios web se construyen de este modo. Cada petición contiene una o varias peticiones más pequeñas. Los valores de retorno se integran en una única respuesta y devueltos al cliente. Precaución, pues esto puede convertirse en un servicio con una interfaz que es tan genérica que básicamente recibe y envía cualquier mensaje. Una vez más, llegamos a la situación en la que la aplicación cliente es incapaz de crear un proxy útil y es dependiente de documentación externa para la interoperabilidad. Estimar cómo equilibrar la agregación de peticiones para mejorar el rendimiento con la complejidad creciente es una de las tareas del arquitecto de la aplicación y sólo puede ser determinado estudiando caso por caso.

4. Usando servicios web para acceso a datos.

Este error viene de un acerca de los servicios web. Algunos arquitectos y desarrolladores tienden a ver los servicios web como un modo de compartir datos. La confusión es comprensible: Microsoft misma ensucia el agua con “mejoras” como la nueva característica de SQL Server 2005 que permite a procedimientos almacenados ser accedidos como servicios web con una par de clicks. Esto permite grandes demos pero mal diseño de aplicaciones.

Los servicios web no proveen simplemente acceso a datos: proveen acceso al conocimiento del negocio de la organización. Organizaciones de todos los tamaños, desde departamentos hasta grandes corporaciones, están definidas por sus conocimientos del negocio. No vas a Starbucks por tus necesidades bancarias, ni el Banco de España hace cafés. Pero las organizaciones a menudo quieren compartir su experiencia con otras organizaciones. Starbucks puede querer que el Banco de España valide una compra con tarjeta de crédito de una de sus bebidas. Esta información compartida significa que Starbucks no tiene que reinventar cómo los pagos con tarjeta se procesan y puede concentrarse en hacer cafés.

¿Cómo una organización implementa su experiencia en el negocio? Una manera es desarrollando aplicaciones personalizadas que creen, mejoren o automaticen el uso de esa experiencia. Ahí es donde aparecen los servicios web y la orientación a servicios: proveyendo acceso a esas aplicaciones a otras organizaciones están compartiendo su conocimiento.

Quizá el mejor ejemplo de un servicio web exponiendo funcionalidad y no datos es el servicio web de Google para buscar en sitios web. ¿Cómo sería de útil el servicio si sólo devolviera datos, información sobre millones de páginas, y tuvieras que buscar a través de ellas? Google pone sus amplios conocimientos de cómo buscar en la web y de ahí viene el valor de su servicio web, no de sus datos.

Cuando desarrollas tus servicios web, recuerda que lo que tus clientes quieren de tu servicio es tu conocimiento del negocio, no sólo tus datos. Deberías cuestionar cada método de un servicio web que únicamente consulta y devuelve datos. Estás colocando la lógica de negocio en el lado erróneo del servicio y forzando a tus clientes a reinventar tu conocimiento del negocio.

5. Confiar en la aplicación cliente

La responsabilidad de un servicio web va más allá de permitir acceso a nuestras reglas de negocio. Es también responsable de proteger el negocio y la integridad de los datos. Muchas veces un servicio web se desarrolla a la vez que la interfaz de usuario que lo consume. El servicio web actúa como “back end” de la aplicación y comúnmente se deja la seguridad a la interfaz de usuario. Si la seguridad se aplica sólo en el lado del cliente de la aplicación, tu servicio web es vulnerable a ataques y la integridad de tu negocio está en bragas.

La clave es separar, tanto en tu cabeza como en el diseño, la seguridad de la interfaz de usuario de la seguridad del servicio web. Cada componente requiere una aplicación correcta de las técnicas de seguridad incluyendo autenticación, autorización, encriptación de los datos… Ten en mente que otras aplicaciones desarrolladas por otras organizaciones podrían utilizar tu “back end”, por tanto asegúrate de que está protegido.

La seguridad es un tema complejo fuera del ámbito de este artículo, pero aquí tienes algunos puntos en los que centrarte:

  • Debes asumir que no puedes confiar en los datos que recibes como parámetros en los métodos del servicio. Los servicios web se despliegan en ASP.NET y por tanto son susceptibles de los mismos tipos de ataques que cualquier aplicación web ASP.NET, incluyendo SQL Injection, DoS, Replay Attacks… Afortunadamente, también puedes utilizar las mismas contramedidas para defender tus servicios de dichos ataques.
  • Los datos que se devuelven deben ser protegidos. Si te preocupa la integridad de los datos a través de la red, la mejor manera es usar SSL para encriptar los datos entre el cliente y el servidor. También puedes aliviar algunas amenazas de SQL Injection o XPath Injection no devolviendo objetos definidos dinámicamente como Datasets y XmlDocuments.
  • La auditoría es una importante y a menudo infravalorada medida de seguridad. Mediante la habilidad de controlar el uso de tus servicios web permites controlar las violaciones de acceso y tienes la capacidad de responder a esos ataques cuando se producen. Claras violaciones de los datos podrían mandar un mensaje a un administrador o cancelar el acceso del usuario al servicio. Ataques DoS se eliminan mediante mecanismos basados en el uso.

Desde el punto de vista de la arquitectura, la clave para evitar problemas de seguridad después del despliegue de un servicio es tener en cuenta la seguridad desde los principios. No te engañes pensando que securizando el cliente basta.

Conclusión

Los servicios web proveen una mejora sin precedentes en cómo se construyen las aplicaciones distribuidas físicamente o en las organizaciones. Visual Studio.NET y el .NET framework permiten desarrollar servicios web de una manera simple y sencilla, incluso los mal hechos. Desarrollando tus servicios evitando estos clásicos errores asegurará a tu organización lo mejor de los servicios web.