Capitulo 12–Usuarios y seguridad de datos

 

Hola nuevamente!! ... perdón la demora. Como actualmente me encuentro en Barcelona trabajando, no he podido hacerme tiempo para mi blog.

Espero que algunos ya hayan podido rendir esta certificación, y para los que no, continúo con el resumen. Espero les sirva.

Muchas gracias por los comentarios!.

  _____________________________________________________________________

 

Usuarios y seguridad de datos

En una empresa es importante controlar quién puede acceder a los datos confidenciales.

Por ej., una aplicación para el seguimiento de gastos debe mostrar a los usuarios sus propios gastos, pero los administradores pueden ver los gastos de otras personas.

La protección de datos requiere la coordinación de varias tecnologías diferentes. Seguridad basada en roles (RBS) que permite controlar lo que los usuarios pueden acceder en función de su nombre de usuario y pertenencias a grupos.

Para proteger los datos, el Framework de. NET proporciona herramientas de criptografía para cifrar, validar y firmar datos.

 

Lección 1- Autentificación y autorización de usuarios

Autentificación es identificar al usuario. A partir de PINs o nombres y contraseñas.

Autorización es el proceso de verificar si el usuario tiene permiso de acceder a algo o no. generalmente sucede después de la autentificación.

 

La clase windowsIdentity

System.Security.Principal. WindowsIdentity nos da acceso al nombre de usuario actual de windows, el tipo de autenticación y un número token. Almacena el resultado de la autenticación, incluyendo su username y token.

Para poder crear una instancia de WindowsIdentity se puede llamar a cualquiera de estos métodos:

  • · GetAnonymous, representa un usuario no autenticado
  • · GetCurrent, devuelve el usuario actual de Windows
  • · Impersonate, devuelve un WindowsImpersonationContext que representa un usuario específico en el sistema.

Ejemplo:

clip_image001

Después de que la variable es asignada, sus propiedades son:

  • · AuthenticationType, cadena que representa el método de autenticación (NTLM normalmente)
  • · IsAnonymous, indica si un usuario anónimo.
  • · IsAuthenticated, indica si es usuario autenticado.
  • · IsGuest, indica si el usuario es invitado.
  • · IsSystem, indica si el usuario es parte del sistema.
  • · Name, una cadena representando el dominio y username de la forma "DOMAIN\Username".
  • · Token, un entero representando el token de autenticación del usuario.

clip_image002

 

Clase WindowsPrincipal

Esta clase nos brinda acceso al group membership. Se debe crear usando una instancia de WindowsIdentity. Por ejemplo:

clip_image003

Otra forma de conseguir una instancia de WindowsPrincipal, es usando el thread principal

clip_image004

El método más importante de esta clase es: IsInRole. Y se puede usar de la siguiente manera:

clip_image006

 

La mayoría de las veces, no se sabrá el nombre del equipo o el nombre de dominio antes de tiempo como para insertarlo en la cadena que se pasa al método IsInRole. En lugar de esto, se puede usar System.Environment.MachineName para obtener los nombres de grupos de la maquina local, o System.Environment.UserDomainName para especificar los nombres de grupos que existen en maquina local o en un Active Directory Domain.

 

Clase PrincipalPermission

La clase PrincipalPermission es útil para realizar acciones de seguridad, imperativas y declarativas. Se pueden combinar cualquiera de las 3 propiedades de esta clase:

  • · Authenticate, indica si requiere que el usuario este autenticado.
  • · Name, string con el username.
  • · Role, string que debe coincidir con uno de los roles principales.

PrinciapalPermission posee el método Demand que verifica si el usuario activo tiene los permisos indicados.

 

Cómo usar la declarativa para realizar peticiones de seguridad para restringir el acceso a los métodos?

La RBS Declarativa restringe el acceso a un método. El problema que tiene es que si en runtime se lanza una excepción por un evento de windows, este la captura y la aplicación se puede detener.

Para usar RBS declarativa, se debe tener en el código:

  • · El método System.AppDomain.CurrentDomain.SetPrincipalPolicy para especificar la política de seguridad.
  • · Bloques try/catch para capturar acceso desprivilegiado y mostrarlo como error.
  • · El Atributo PrincipalPermission para declarar requerimientos de acceso a método.

Ejemplo:

clip_image007

Ejemplo con varias declarativas:

clip_image009

 

Cómo usar el método imperativo de seguridad basado en demandas para crear aplicaciones que restrinjan el acceso a porciones de su lógica?

El método imperativo de demandas RBS le permiten restringir las porciones de un método, mientras que las demandas RBS declarativa los restringen en su totalidad.

Para usarla se deben de tener 4 elementos:

  • · El método System.AppDomain.CurrentDomain.SetPrincipalPolicy para especificar las políticas de seguridad principales.
  • · Bloques Try/catch para capturar accesos no privilegiados.
  • · El objeto PrincipalPermission con propiedades acordes a las restricciones que se quieren imponer.
  • · Una llamada al método PrincipalPermission.Demand para declarar los requerimientos de acceso al método.

Ejemplo, el código una lanza excepción (que se captura con System.Security.SecurityException), si el usuario no es miembro del grupo Administrators:

clip_image011

 

Como implementar usuarios y roles personalizados?

Si se necesita autenticar a los usuarios contra una base de datos personalizada, se pueden utilizar las interfaces System.Security.Principal.IIdentity y System.Security.Principal.IPrincipal. Además se pueden ampliar aplicando clases de identidad propias, con propiedades y funcionalidades adicionales.

 

Cómo crear una clase de identidad personalizada?

La interfaz IIdentity sirve para crear clases de identidad personalizadas.

WindowsIdentity, FormsIdentity y PassportIdentity son clases que implementan esta interfaz. Mientras que GenericIdentity ofrece una implementación flexible de IIdentity.

Para implementar esta interfaz, se deben usar las siguientes propiedades:

  • · AuthenticationType, string que almacena la descripción del mecanismo de autenticación del usuario.
  • · IsAuthenticated, se setea este valor en true cuando el usuario ha sido autenticado.
  • · Name, string que guarda el username.

Además de este, se debe realizar un constructor que defina cada una de las propiedades.

Ejemplo:

clip_image012

 

Cómo crear una clase principal personalizada?

WindowsPrincipal y GenericPrincipal están basadas en la interfaz IPrincipal. Los objetos basados en esta interfaz representan el contexto de seguridad de un usuario, incluyendo la identidad del usuario y cualquier rol o grupo al que pertenezca.

Para implementar la interfaz IPrincipal, debemos de implementar al menos un constructor, una propiedad y un método. El constructor debe aceptar un objeto IIdentity y un arreglo de strings que contienen los roles de identidad. La propiedad que se debe implementar es IPrincipal.Identity que debe devolver el identity principal del objeto.

El metodo IPrincipal.IsInRole que toma un string y un rol y retorna true cuando el identity principal es un miembro de ese rol; sino retorna false.

También se pueden añadir otras funcionalidades sobrescribiendo IPrincipal:

  • · Añadir una propiedad Roles que devuelva un arreglo de strings conteniendo los roles del usuario.
  • · Agregar los métodos IsInAllRoles y IsInAnyRole que indiquen si el usuario es miembro de múltiples roles.
  • · Añadir los métodos IsHigherThanRole y IsLowerThanRole que habiliten jerarquía en los grupos de membresía.

Ejemplo de implementación:

clip_image013

 

Como crear modelos simples de privilegios de usuario personalizados?

Si solo se necesitan las funcionalidades básicas de IIdentity y IPrincipal, se debe usar System.Security.Principal.GenericIdentity y System.Security.Principal.GenericPrincipal. Estas clases implementan solo las propiedades y métodos requeridos por las interfaces. Cada uno ofrece constructores que la aplicación debe de usar para especificar las propiedades de cada clase.

GenericIdentity: tiene 2 constructores. Se puede usar un username, o un username y el tipo de autenticación.

clip_image015

GenericPrincipal: tiene un constructor que pide un GenericIdentity y un arreglo de string con los roles de identidad.

clip_image016

Después de crear el objeto principal, principal.IsInRole("Users") debería retornar true.

 

Cómo utilizar demandas RBS con identidades personalizadas y principals?

Si es que se define custom IIdentity y IPrincipal, o se usa GenericIdentity y GenericPrincipal, se puede usar declarativa e imperativa RBS estos pasos:

1. Crear un objeto IIdentity o GenericIdentity que represente al usuario actual.

2. Crear un objeto IPrincipal o GenericPrincipal basado en mi objeto IIdentity

3. Setear Thread.CurrentPrincipal a mi objeto IPrincipal

4. Adherir una declarativa o imperativa RBS.

 

Manejando excepciones en Streams

Para manejar autenticaciones remotas, se usa: System.Net.Security.NegotiateStream o System.Net.Security.SslStream.

Estas excepciones pueden ser:

  • · System.Security.Authentication.AuthenticationException: Una excepción de este tipo indica que se debe solicitar al usuario credenciales diferentes y que vuelva a intentar la autenticación.
  • · System.Security.Authentication.InvalidCredentialException: indica que el stream no se encuentra en un estado válido, y no se puede volver a intentar la autenticación.