EF 4.1 Code First, ¿map private members?

 

 

Bueno, lo prometido es deuda, y como a muchos “amiguetes” les prometí no abandonar la serie sobre mapping de EF 4.1 puest aquí sigo al ataque. Se que alguno me recordará que también tengo pendiente escribir el apéndice sobre EF 4.1 que permita completar el libro de EF que acabo de publicar, con respecto a esto, me gustaría, aprovechando la coyuntura hacer dos anotaciones. La primera es que más que un apéndice-capítulo se está convirtiendo casi en un libro aparte, el caso es que son tantas cosas para contar que uno va degenerando en páginas y páginas, espero que provechosas. Le segunda anotación que me gustaría hacer es que trataré por todos los medios que aquellos que habéis comprado el libro podáis acceder a este apendice/nuevo libro de una forma “nada” costosa.

 

Venga al tajo, la idea con este y algún nuevo post, es ir ampliando la información sobre mapping o bien creando código que nos ayude con este trabajo. La idea de hacerlo un poco más cañero de lo normal viene del hecho que últimamente he leído algún post como este de José Ramaniello que me ha parecido bastante un poco sesgado  y, por lo tanto, aquí estamos.

 

En ocasiones podemos encontrarnos escenarios dónde necesitemos que nuestras entidades puedan mapear una propiedad no pública, si, has escuchado bien. El ejemplo más prototípico de esto es por ejemplo en un agregado raiz ocultar el acceso directo a una navegación, de tal forma que, las operaciones de agregar entidades al agregado se puedan hacer por medio de un método del mismo y no directamente por una colección. Cierto es, que por defecto EF 4.1 no nos permite el mapeo de elementos privados, por lo menos en la superficie del API, sin embargo, rebuscando un poco y no conformándose es medianamente sencillo ver que tenemos solución a este problema. Realmente, cuando mapeamos una propiedad  escribimos algo similar a lo siguiente:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
            modelBuilder.Entity<Customer>()
                        .Property(p => p.FirstName)
                        .HasMaxLength(200);
}

Pues bien, el método Property, que admite una expresión lambda, realmente no tiene porque circunscribirse a propiedades públicas, es decir, podríamos crear, gracias a las capacidades de los árboles de expressiones, una firma idéntica a la solicitada por este método sin necesidad de que el acceso fuera a un elemento público, ¿como? Pues bien, en el siguiente método extensor podéis ver como generar un nuevo método Property con esta capacidad.

 

        /// <summary>
        /// Extension method for map private properties
        /// <example>
        /// modelBuilder.Entity{Customer}()
        ///             .Property{Customer,int}("Age")
        ///             .IsOptional()
        /// </example>
        /// </summary>
        /// <typeparam name="TEntityType">The type of entity to map</typeparam>
        /// <typeparam name="KProperty">The type of private property to map</typeparam>
        /// <param name="entityConfiguration">Asociated EntityTypeConfiguration</param>
        /// <param name="propertyName">The name of private property</param>
        /// <returns>A PrimitivePropertyConfiguration for this map</returns>
        public static PrimitivePropertyConfiguration Property<TEntityType, KProperty>(this EntityTypeConfiguration<TEntityType> entityConfiguration, string propertyName)
            where TEntityType : class
            where KProperty:struct
        {

            var propertyInfo = typeof(TEntityType).GetProperty(propertyName, BindingFlags.NonPublic
                                                                        |
                                                                        BindingFlags.Instance
                                                                        |
                                                                        BindingFlags.Public);
            if ( propertyInfo != null ) // if private property exists
            {
                ParameterExpression arg = Expression.Parameter(typeof(TEntityType), "parameterName");
                MemberExpression memberExpression = Expression.Property((Expression)arg, propertyInfo);

                //Create the expression to map
                Expression<Func<TEntityType, KProperty>> expression = (Expression<Func<TEntityType, KProperty>>)Expression.Lambda(memberExpression, arg);


                return entityConfiguration.Property(expression);
            }
            else 
                throw new InvalidOperationException("The property not exist");
        }

Ahora, gracias a este método extensor podríamos escribir mapeos con el siguiente:

 

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Entity<Customer>()
                 .Property<Customer,int>("PrivateMember");
                        
}
Y ahora que sigue? pues os pido que a los que os guste jugar que hagáis esto mismo para las propiedades de navegación…. 

¿Os ha gustado? Pues esto, y muchas cosas más ya están la cocina del nuevo apéndice-capitulo, perdón por la promoción :-/, algunas, para abrir bocar y quizás, para cerrar alguna, las iremos poniendo en sucesivas entradas.

 
 
Saludos
Unai
The klingon note: Debugging? Klingons do not debug. Bugs are good for building character in the user!
 

WIF es sencillo, úsalo #2

En nuestra anterior entrega empezamos describiendo los motivos de la entrada en juego de WIF y de cuales son las principales preguntas a las que tenemos que dar respuesta, a lo largo de esta segunda entrada, trataremos de poner de manifiesto algunos conceptos que es necesario entender/comprender  así como los elementos de trabajo que tendremos..

 

Algunos conceptos para empezar..

 

Dentro del escenario planteado en la entrada anterior podemos observar distintos conceptos como los siguientes:

 

  • Security Token Service

Untitled 

 

 

Un Security Token Service, más comunmente llamado STS, se encarga, a grosso modo, de entregarnos, una vez autenticados, un token des seguridad (security token). Para realizar esta tarea, disponemos de un protoco estándard que tanto .NET como otras tecnologías podrían implementar. Este protocolo, se conoce como WS-Trust y sobre su versión 1.3 puede obtener más información aquí, Windows Identity Foundation implementa este protocolo por medio de un servicio WCF cuyo contrato, IWSTrust13SyncContract, está definido en Microsoft.IdentityModel.Protocols.WSTrust. Realmente WS-Trust es un protocolo que funciona con paquetes SOAP por lo tanto aquellos elementos que quieran interactuar con el para, emitir, renovar o cancelar un token tendrán que entender  SOAP. A estos clientes, generalmente se les conoce como Clientes Activos. Lógicamente, hay escenarios dónde los clientes que necesiten un token de seguridad no entienden SOAP, por ejemplo un navegador web y html, para estos escenarios, hay un conjunto de recetas que tenemos disponibles para solventar el problema, este conjunto de recetas se conoce como WS-Federation, y sobre esto puede obtener más información en el siguiente enlace.

 

  • Security Token

 

Untitled2

 

 

Acabamos de hablar del encargado de emitir, renovar o cancelar tokens de seguridad así como de los protocolos que usa pero ¿qué es un token de seguridad?  Un token de seguridad no es más que un conjunto de claims (aserciones, afirmaciones) que representan atributos de una entidad, por ejemplo el nombre, la edad, el correo electrónico, cualquier cosa en definitiva ( lógicamente existe un conjunto de claims comunes como name,role, action etc, pero nosotros podemos definir nuestras propias claims). Como es de esperar, este contenido de claims está securizado por medio de una firma digital que garantice que en el proceso de emisión y recepción nadie pueda tocar este elemento. La definición de este elemento se hace por medio de un lenguaje XML conocido como SAML ( Security Assertion Markup Language ).

 

  • Relaying Party
 

Untitled3

 

 

Una Relying Party no es má que aquella aplicación o servicio que tiene externalizado el proceso de autenticación en un Security Token Service. Hablando de lo que nosotros conocemos sería cualquier aplicación ASP.NET o Servicio WCF que delega su proceso de autenticación en un STS con un proveedor de identidad determinado

 

 

 

Con estas pequeñas y someras definiciones ya nos hemos adentrado en la mayoría de los conceptos que tenemos que entender dentro de la seguridad orientada a claims. En las siguientes entradas, veremos como mapear todo esto con ejemplo de código, tanto para clientes activos como para clientes pasivos.

 

 

Saludos

Unai

WIF es sencillo, úsalo!! #1

 

Bueno, como reza el título la idea de esta serie (llevo ya un tiempo escribiendo alguna serie que otra y me parece una gran idea para el blog) es intentar mostrar las bondades de Windows Identity Foundation y de su uso dentro de nuestros desarrollos en .NET. Aunque como comenté en otras ocasiones a mi no me gusta hacer los típicos 101, y ya de sobra he explicado que el motivo no es por prepotencia sino porque considero que son materiales que no aportan nada al estar la Web inundado de este tipo de escenarios, si me gustaría en este caso empezar desde las cosas más básicas hasta escenarios más complejos.

Por una u otra razon, a excepción de contadas ocasiones, la adopción de WIF (al menos hasta dónde yo conozco) es más bien excasa. Hablando sobre los motivos de esto en las jornadas del Cloud Power, una de las conclusiones que salieron fué un motivo podría ser el hecho de que generalmente a los desarrolladores nos da miedo o no nos gusta tener que enfrentarnos con temas de seguridad, más si cabe, si ya tenemos ‘ñapas’ o soluciones más o menos buenas para algunos de los escenarios que tengamos entre manos. A lo largo de esta serie, intentaré mostrar como realmente el trabajo con WIF es sencillo y que a los desarrolladores, lo único que nos va a aportar es facilidad y sencillez de trabajo, amén de librarnos de trabajo en nuestros diferentes clientes :-)…

 

Empezemos por el principio, la motivación.

 

Untitled

Que nos aporta WIF? Cual es el problema a resolver? Sin lugar a dudas, estas deberían ser las dos primeras preguntas que nos deberíamos hacer, tanto para esta como para cualquier otra tecnología, antes de pensar en usar esta tecnología. La respuesta es variada y seguramente, espero, en muchos de los siguientes argumentos  estará usted de acuerdo.

  1. Experiencia en seguridad

Hasta dónde yo se ( lógicamente no me conozco los planes de estudio de todo el mundo) la seguridad suele ser una tarea sobre la que se pasa de puntillas, incluyendo aquí problemas de criptografía, problemas con certificados, ataques, canonicalización etc etc.. Hasta ahora, generalmente los problemas de seguridad que teníamos que resolver se podían atajar directamente con un usuario y contraseña ( cubramos un tupido velo respecto a como se hacia en muchos sitios),  sin embargo, en este mundo cada vez más global, elementos como los tokens de seguridad, la autenticación en proveedores terceros ( token facebook, twitter, partners, open id, oauth… ) son cada vez más comunes, el manejo de estos elementos, la mezcla con los nuestros, y otros patrones de seguridad hacen que necesitemos en muchos casos muchos conocimientos de seguridad ( muchos muchos)

  1. La identidad es ya un problema complejo

Como acabamos de comentar, los escenarios de seguridad son cada vez más complejos, nuestras aplicaciones ya no se acceden solamente desde la intranet o internet, por lo tanto nuestros repositorios de usuarios tienen que ser capaces de manejar diferentes tipos de proveedores ( AD, custom, Google,Yahoo, Facebook etc….), a mayores, escenarios como la federeación de partners, la delegación vienen a completar el conjunto de escenarios de seguridad que tenemos que cubrir como desarrolladores.

A mayores de esto, hoy en dia la identidad ya no solamente viene representada por un par usuario/contraseña, la identidad, tanto de un usuario como de una máquina, puede venir representada por diferentes atribuciones, atribuciones que hoy en dia tenemos que separar de nuestros repositorios de usuarios, obligándonos otra vez a “estar atados a un repositorio determinado”

  1. Interoperabilidad

Como yo suelo decir, “!Somos los mejores en este mundo, pero…. por suerte no somos los únicos!” y por lo tanto nuestros mecanismos de seguridad  (autenticación / autorización) deberían de ser interoperables con otras tecnologías…..

 

WIF, una solución…

 

Untitled2

NOTA: Aunque la figura anterior hace referencia al trabajo en la web, realmente este mismo criterio se aplicaria a un servicio WCF.

 

Una posible solución a este problema es externalizar el proceso de seguridad de nuestras aplicaciones, hacer un “outsourcing de la autenticación” delegando en un “experto” los distintos problemas y escenarios que se nos puedan plantear. WIF y el modelo de seguridad basado en “claims” nos permiten realizar esta tarea de una fomra realmente sencilla.

 

Lógicamente este modelo implica una serie de conceptos y definiciones que por ahora desconocemos pero que trataremos de explicar en la siguiente entrada de esta serie, que esperemos sea pronto….

 

Saludos

unai

[EVENTO] SCRUM WEEK: Arquitecturas Ágiles y Coding Dojo

 

La semana del 4 de Abril tengo la suerte de participar en la semana ágil por excelencia, la SCRUM WEEK, esta semana, dedicada enteramente a la agilidad desde diferentes puntos de vista, contará con ponentes de la talla de Rodrigo Corral , Jose Luis Soria ( recién llegado del Tech Ed de Asia ) y Ángel Medinilla.

Durante esta semana trataré de abordar principios de arquitectura ágil desde un vistazo práctico en el que todos participemos. Aunque aún no está confirmado trataremos de que durante estas sesiones participe también algún otro ponente de prestigio, pero esto ya lo veremos 🙂

 

Unai

[Evento] Windows Identity Foundation + Azure = Cloud Power

Mañana miércoles, junto a unos cuantos compañeros ( la mayoria amigos ) ponentes tengo la suerte de impartir uno de los tracks del evento Destino la Nube. Concrétamente la sesión “Seguridad en la nube basada en Claims: Windows Azure Access Control Sevice” dentro del track 3 a las 12:30 AM.

 

Espero veros por allí y hablar con todos vosotros durante el evento, se que ya hay una cantidad terrible de personas registradas para lo que esperamos sea un maravilloso evento…

 

Más información en el portal del evento

 

Unai