Pasar Credenciales en Http Header Authorization

Noviembre 27, 2008 :: Posted by - Emilio Torrens :: Category - , ,

Me he estado volviendo medio loco estos días intentando conectar con el servicio de un tercero, la documentación no era todo lo clara que uno espera…

Intente pasarle las Credenciales como NetworkCredentials en el HttpRequest y nada, añadiendo cabeceras de autentificación al mensaje SOAP y nada, al final las espera en una cabecera Http.

¿Como se pasan allí? pues así:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("la url del servicio");

req.Headers.Add("SOAPAction", "la accion");
req.ContentType = "application/soap+xml";
req.Accept = "text/xml";
req.Method = "POST";
byte[] authBytes = Encoding.UTF8.GetBytes(("Usuario:Pass").ToCharArray());
req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(authBytes));       

String Compile

Noviembre 25, 2008 :: Posted by - Emilio Torrens :: Category -

Con CSharpCodeProvider y  ICodeCompiler podemos escribir y ejecutar código al vuelo.

Cuando vi esto en una demo de Microsoft no me pareció algo excesivamente útil, pero estos días me he encontrado con un problema que he podido resolver gracias a esto.

Resulta que tengo un servicio al que le envían documentos XML y no tengo una manera fija para saber quien envía esos documentos, algunos es por el Document Element, otros por un valor de XPath, y cosas así, así que para resolverlo dejo que el usuario configure la condición y la compilo y la ejecuto.

Aquí dejo un ejemplo de código:

using System;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;
using Microsoft.CSharp;

namespace Macros
{
    public interface IStrCode
    {
        bool Eval(string Condicion);
    }

    public class StrCodeManager
    {
        public static void Test()
        {
            bool result = IsValid("\"1234\".Length == 4");
            result = IsValid("2 + 2 == 5");
            result = IsValid("\"Hola Que tal\".IndexOf(\"Hola\") != 0");
        }

        public static bool IsValid(string Condicion)
        {
            string SourceString =
                @"using Macros;
                        public class StrCode : IStrCode
                        {
                            public bool Eval(string Condicion)
                            {
                                return @@Condicion@@;
                            }
                        }"
                    .Replace("@@Condicion@@", Condicion);

            CSharpCodeProvider codeProvider = new CSharpCodeProvider();
            ICodeCompiler icc = codeProvider.CreateCompiler();

            CompilerParameters parameters = new CompilerParameters();
            parameters.GenerateExecutable = false;
            //Aqui añadimos las referencias necesarias
            parameters.ReferencedAssemblies.Add("System.dll");
            //Esta es la referencia a esta dll para que tenga acceso al interface
            parameters.ReferencedAssemblies.Add("My.dll");
            CompilerResults results = icc.CompileAssemblyFromSource(parameters, SourceString);

            if (results.Errors.Count != 0)
            {
                StringBuilder stringBuilder = new StringBuilder();
                foreach (CompilerError CompErr in results.Errors)
                {
                    stringBuilder.AppendLine(CompErr.ErrorText);
                }

                throw new Exception(stringBuilder.ToString());
            }

            Assembly As = results.CompiledAssembly;

            foreach (Type tipo in As.GetTypes())
            {
                if (tipo.GetInterface("IStrCode") != null)
                {
                    IStrCode eval = (IStrCode) Activator.CreateInstance(tipo);
                    return eval.Eval(Condicion);
                }
            }

            throw new Exception("");
        }
    }
}

Web.config y configSource

Noviembre 21, 2008 :: Posted by - Emilio Torrens :: Category -

configSource es un atributo que nos permite indicar otro fichero .config para una sección.

Por ejemplo, que queremos tener nuestra configuración especifica en un fichero aparte para que sea menos lioso

<appSettings configSource ="mySettings.config" />

Que queremos tener las cadenas de conexión de SQL en otro sitio

<connectionStrings configSource="MyConns.config" />

Esto nos permite tener un web.config menos lioso, dejar que gente de menos nivel configure las aplicaciones sin tocar el web.config e incluso pasar a producción sin tener que acordarte de todos los cambios que tienes que hacer en el web.config.

Como saltarse los certificados al hacer conexiones HTTPS

Noviembre 20, 2008 :: Posted by - Emilio Torrens :: Category - ,

Si queremos hacer peticiones a un sitio https y no tenemos el certificado o no queremos usarlo la manera es la siguiente:

1- Crear una clase que implemente ICertificatePolicy donde la validación siempre devuelva true para pasársela al  CertificatePolicy del ServicePointManager

 public class TrustAllCertificatePolicy :ICertificatePolicy
    {
        public TrustAllCertificatePolicy()
        {
        }

        #region ICertificatePolicy Members

        public bool CheckValidationResult(ServicePoint sp,
                      X509Certificate cert,
                      WebRequest req,
                      int problem)
        {
            return true;
        }

        #endregion
    }

2-Pasarle la clase al ServicePointManager antes de hacer la petición

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();

A partir de eso podemos hacer las peticiones sin el certificado.