[ASP.NET] Separar los Settings de nuestras librerías de clases en nuestro web.config en archivos individuales y encriptarlos
Vamos a empezar viendo un ejemplo de lo que se pretende para que nos quede más claro. Tenemos la siguiente solución ficticia compuesta por 3 proyectos (La aplicación web y 2 librerías de clases para acceder a diferentes servicios web):
Como podéis observar, cada librería de clases tienes su propio fichero de Settings, donde almacenamos por ejemplo la url del servicio y las credenciales en el caso que se necesiten. Por ejemplo vamos a ver como quedaría el fichero de Settings del servicio web de Paypal:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings"
type="System.Configuration.ApplicationSettingsGroup, System, >
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
<section name="SettingsExample.WebServices.Paypal.Properties.Settings"
type="System.Configuration.ClientSettingsSection,
System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<SettingsExample.WebServices.Paypal.Properties.Settings>
<setting name="PaypalUser" serializeAs="String">
<value>paypal</value>
</setting>
<setting name="PaypalPassword" serializeAs="String">
<value>paypal</value>
</setting>
<setting name="SettingsExample_WebServices_Paypal_Paypal_AplicacionesWebService"
serializeAs="String">
<value>http://www.paypal.com/services/paypal.asmx</value>
</setting>
</SettingsExample.WebServices.Paypal.Properties.Settings>
</applicationSettings>
</configuration>
El siguiente paso una vez terminados las librerías de los servicios sería consumirlas desde nuestra aplicación web de eCommerce y como no, nos harían falta estas Settings en nuestro web.config para que funcionen correctamente.
Lo que mucha gente hace por desconocimiento (Creo yo) es, o bien poner las settings como Embebed Resource de la dll o ponerlas directamente en el Web.Config, haciendo a este crecer en tamaño y complicar su mantenimiento por parte de administradores.
Para mí la solcuión ideal es meter estas Settings en ficheros .config independientes con un nombre descriptivo y hacer referencia a ellos en el Web.config y a continuación vamos a ver como lo hacemos:
Abrimos nuestro Web.Config y localizamos el elemento <configSections> y metemos un nuevo sectionGroup para hacer referencia a nuestros Settings como se muestra en el siguiente código:
<sectionGroup name="applicationSettings"
type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, >
Culture=neutral, PublicKeyToken=b77a5c561934e089"
<section name="SettingsExample.WebServices.Paypal.Properties.Settings"
type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
<section name="SettingsExample.WebServices.Products.Properties.Settings"
type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</sectionGroup>
Una vez hecho esto, vamos a añadir nuestro nuevo sectionGroup al Web.Config, haciendo referencia a nuestros ficheros .config especificando el atributo configSource:
<applicationSettings>
<SettingsExample.WebServices.Paypal.Properties.Settings
configSource="PaypalSettings.config" />
<SettingsExample.WebServices.Products.Properties.Settings
configSource="ProductsSettings.config" />
</applicationSettings>
Y por último añadimos los ficheros .config a nuestra aplicación web (Junto con el Web.Config):
PaypalSettings.config
<?xml version="1.0"?>
<SettingsExample.WebServices.Paypal.Properties.Settings>
<setting name="PaypalUser" serializeAs="String">
<value>paypal</value>
</setting>
<setting name="PaypalPassword" serializeAs="String">
<value>paypal</value>
</setting>
<setting name="SettingsExample_WebServices_Paypal_Paypal_AplicacionesWebService"
serializeAs="String">
<value>http://www.paypal.com/services/paypal.asmx</value>
</setting>
</SettingsExample.WebServices.Paypal.Properties.Settings>
Quedando la solución de esta manera:
Ahora te dicen:
- ¿Pero los usuarios y contraseñas se ven en el fichero?
A lo que puedes responder:
- No hay problema, vamos que te enseñe a encriptarlos :)
Para ello vamos a hacer uso de una utilidad que yo creo que ya es conocida por todos aspnet_regiis
- Sí estas en tú máquina de desarrollo (En mi caso) podemos arrancar la consola de VS como administrador (Visual Studio 2008 Command Prompt)
- Sí estas en un server de desarrollo, preproducción, producción, depende de la versión de NET que estas ejejcutando y depende de sí es 32 ó 64 bits:
C:\Windows\Microsoft.NET\Framework64\vXXXXXX (64)
C:\Windows\Microsoft.NET\Framework\vXXXXXX (32)
y ponemos la siguiente instrucción para encriptar la section concreta con ruta física de directorio (Para más información sobre aspnet_regiis):
aspnet_regiis –pef “applicationSettings” “ruta física de tu aplicación web”
Y al ejecutar nos fallará:
El porque del fallo es que no es una section sino un sectionGroup y por tanto tenemos que especificar la section que queremos encriptar (En este caso el archivo config de Paypal):
Vamos a nuestro fichero Paypal.Config y sorpresa:
<?xml version="1.0"?>
<SettingsExample.WebServices.Paypal.Properties.Settings configProtectionProvider="RsaProtectedConfigurationProvider">
<EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>ZoeRp7/................=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>/+Pk/AvWFXhTqNFOciGR7A/...........==</CipherValue>
</CipherData>
</EncryptedData>
</SettingsExample.WebServices.Paypal.Properties.Settings>
Y para desencriptarlo:
Espero que os sirva ;)
Saludos.