Sv Community El Salvador

Soporte y Tecnología => Programación => .NET => Topic started by: eduardo91 on July 31, 2012, 07:22:13 pm

Title: Ocultar Paginas segun tipo de usuarios
Post by: eduardo91 on July 31, 2012, 07:22:13 pm
Estoy realizando una aplicación asp.net que sera el proyecto final de la materia de programación en la universidad, el proyecto es crear un tipo portal donde habrán 2 tipos de usuarios alumnos y docentes he creado 2 master page con sus respectivos menús y paginas según el tipo de usuario y cuando se loguean recupero el tipo de usuario que es y según eso lo redirecciono a la master page con su menú y paginas correspondientes pero me tengo una duda.

Como ya dije cuando se loguea según el tipo de usuario lo redirecciona a diferentes paginas  pero resulta que si después que se loguea escribe en la barra de direcciones una pagina que no corresponde a su tipo de usuario la pagina se carga entonces quiero controlar esto que si escribe en la barra de direcciones una pagina que no sea de su tipo de usuario no la muestre.

Como podría implementarlo no quiero usar membership porque ya tengo estructurada mi bd, así que quiero encontrar una manera de resolver lo que planteo por medio de código.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: el-mago on July 31, 2012, 08:15:13 pm
hace en cada pagina o como un include, para que no escribas tanto en c/u... una comprobación simple, digamos que almacenaste en la variable "tipo", el tipo de usuario.

0 = usuario normal
1 = docente

if(tipo == 1)
se muestra la pagina a la que el solo los docentes tienen acceso
else
lo regresa al master de usuario normal, con el código de redireccion vea.

o mas simple:
if(tipo != 1)
redireccion

esto iria al cargar la pagina, antes de cualquier impresión de codigo. y solo en las paginas donde los docentes tienen acceso

algo asi es la idea, no es el codigo exacto pero la idea asi va..

Suerte.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: edu_guerr on July 31, 2012, 08:21:48 pm
Con una sesion no te servira?  crear una sesion de usuario(docente o alumno) en el login, y con esa sesion validas a quien mostrar la pagina.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: eduardo91 on July 31, 2012, 09:11:57 pm
hace en cada pagina o como un include, para que no escribas tanto en c/u... una comprobación simple, digamos que almacenaste en la variable "tipo", el tipo de usuario.

0 = usuario normal
1 = docente

if(tipo == 1)
se muestra la pagina a la que el solo los docentes tienen acceso
else
lo regresa al master de usuario normal, con el código de redireccion vea.

o mas simple:
if(tipo != 1)
redireccion

esto iria al cargar la pagina, antes de cualquier impresión de codigo. y solo en las paginas donde los docentes tienen acceso

algo asi es la idea, no es el codigo exacto pero la idea asi va..

Suerte.

Algo así había pensado, pero esto me tocaría ir haciéndolo en todas las paginas que solo los docentes tengan acceso vdd? y el código  iría en el evento load de cada pagina si no me equivoco
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: eduardo91 on July 31, 2012, 09:18:59 pm
La mejor forma no es redirigir de un índice a una u otra página, además de que no es muy escalable si después se necesita agregar más categorías (habría que modificar un documento "semiestático" por categoría).

La forma más directa en la que se pueda evitar ese problema es tener el índice en cuestión (una única URL para un único índice), y que no redirija a diferentes páginas, sino que esta imprima directamente una "plantilla" para cada tipo de usuario. Así todos los documentos de la aplicación web sirven solo la interfaz para cada tipo de usuario.

Idealmente sería una serie de IFs que determinan qué plantilla imprimir, y esas plantillas deberían estar fuera del directorio accesible desde Internet, o por lo menos muy bien escondidos, en directorios que nadie pueda encontrar en Internet.
Te capte mas o menos la idea pero la vdd no sabría como implementarla, la aplicación no estará en internet es un proyecto para hacerlo de forma local
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: el-mago on July 31, 2012, 09:20:59 pm
Con una sesion no te servira?  crear una sesion de usuario(docente o alumno) en el login, y con esa sesion validas a quien mostrar la pagina.
Si, creo yo que seria lo ideal, que se creara la variable de session al momento de un correcto login, pero es el mismo punto, el ya tiene el tipo de usuario almacenado en una variable.

Algo así había pensado, pero esto me tocaría ir haciéndolo en todas las paginas que solo los docentes tengan acceso vdd? y el código  iría en el evento load de cada pagina si no me equivoco
yo te aconsejo hacer un include, como lo dije anteriormente. digamos

docentes.aspx
<% codigo de comprobación a nivel 1 %>

estudiantes.aspx
<% codigo de comprobación a nivel 0 %>

y pones en tu pagina dentro del body <!-- #INCLUDE FILE="docentes o estudiantes.aspx" -->  según sea tu elección de comprobación si queres restringir acceso a docentes a algunas de estudiantes. Con esto estas incluyendo el codigo de docentes.aspx en la pagina y no tenes que digitar el codigo de docentes.aspx en c/u, solo colocas la linea del include.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: eduardo91 on July 31, 2012, 09:23:06 pm
Con una sesion no te servira?  crear una sesion de usuario(docente o alumno) en el login, y con esa sesion validas a quien mostrar la pagina.
Te refieres de hacerlo como me lo dijeron en la primera respuesta de ir validando el tipo de usuario en las paginas y en función de esto mostrar o no el contenido.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: eduardo91 on July 31, 2012, 09:29:27 pm

docentes.aspx
<% codigo de comprobación a nivel 1 %>

estudiantes.aspx
<% codigo de comprobación a nivel 0 %>

y pones en tu pagina dentro del body <!-- #INCLUDE FILE="docentes o estudiantes.aspx" -->  según sea tu elección de comprobación si queres restringir acceso a docentes a algunas de estudiantes. Con esto estas incluyendo el codigo de docentes.aspx en la pagina y no tenes que digitar el codigo de docentes.aspx en c/u, solo colocas la linea del include.
A lo de include no lo entiendo muy bien nunca lo he usado. te refieres a que dentro de las etiquetas <%  %> estaría el código en c# para comprobar que tipo de usuario es y en base a esto decidir si muestra o no la pagina
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: el-mago on July 31, 2012, 09:37:15 pm
si, ahi va el codigo de comprobación.
luego lo guardas como docentes.aspx*ejemplo vea
y ahi queda el codigo, despues pones en las paginas que queres que se ejecute ese codigo, el codigo del include, tal como lo dice lo incluye, es como que el codigo estubiese en la pagina, pero no, esta en otra y este codigo lo jala.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: eduardo91 on July 31, 2012, 09:56:15 pm
si, ahi va el codigo de comprobación.
luego lo guardas como docentes.aspx*ejemplo vea
y ahi queda el codigo, despues pones en las paginas que queres que se ejecute ese codigo, el codigo del include, tal como lo dice lo incluye, es como que el codigo estubiese en la pagina, pero no, esta en otra y este codigo lo jala.
Ya te entendí es como tipo  php que haces los include, mañana pruebo y comento como me fue.
Gracias por las respuestas.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: Non Servium on July 31, 2012, 10:31:09 pm
Yo lo que considero más conveniente para estos casos es crear perfiles para usuarios. También una tabla en la bd con menús y una asociativa entre ambas. De la siguiente forma:

Menús
Id_Menu
Nombre
Url (aquí irá por ejemplo "~/Catalogos/Alumnos.aspx")

Usuarios
Id_Usuario
Id_Perfil
NombreUsuario
Identificador
Contraseña

Perfiles
Id_Perfil
NombrePerfil

PerfilesPermisos
Id_PerfilPermiso
Id_Menu
Id_Perfil
PermisoLectura
PermisoEscritura
PermisoEliminacion

Poniendo simplemente los campos básicos de la estructura...

Luego para no escribir en cada página el código para validar, en el "OnInit" (hacer override de la función) de la master podes validar si el Id_Perfil de alguna sesión está en en "AppRelativeVirtualPath" (Url) con un query relacionando las tablas, si no está usas Response.Redirect("~/Inicio.aspx")

Es una idea casi vaga pero acomodá las ideas y te queda una aplicación tentativamente segura...
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: Juancho on July 31, 2012, 11:52:31 pm
Vaya mita la forma mas fácil es utilizar el Web.Config y CustomMemberShipProvider
Creas 2 carpetas, una donde vas a guardar las paginas para docentes y otra para las paginas d usuraio normal.
Luego desde el Web.Config, haces una denegación d acceso a la carpeta de docentes y especificas que usuarios van a tener acceso, y lo mismo para la otra carpeta.
Y listo, eso es todo.

Si quieres hacerlo ya con roles, tendrías que implementar además un CustomRoleProvider, entonces con ellos en el web.config en vez d conceder a usuario específicos, vas a conceder a usuario que estén en el rol X...

como ya tienes tu propia base de datos es obligación que hagas tus CustomMembershipProvider y CustomRoleProvider para que se adecue. A tu sistemas
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: mxgxw on August 01, 2012, 08:19:21 am
Esto es algo que se necesita hacer muy frecuentemente en casi cualquier portal y usualmente no es tan sencillo como parece.

Yo generalmente utilizo permisos por grupo/objeto.

Cada usuario pertenece a un grupo y cada grupo tiene acceso a ciertos objetos. Al final intento crear una clase que verifique que el grupo tenga acceso al objeto especificado y en base a eso se permite el acceso.

Por ejemplo:

Tabla usuarios:
IdUsuario (PK)

Tabla grupos:
IdGrupo (PK)

Tabla usuarios_grupo
IdGrupo (PK)(FK)
IdUsuario (PK)(FK)

Tabla Objetos:
IdObjeto (PK)
NameObjeto (UNIQUE idx)

Tabla Acceso_Objetos
IdGrupo (PK)(FK)
IdObjeto (PK)(FK)

Tendrías que crear una clase que tome el usuario y ejecute un código como este:

Code: [Select]

SELECT
  COUNT(*) AS ACCESO_OBJETOS
FROM  acceso_objetos
INNER JOIN
  usuarios_grupo ON
  usuarios_grupo.IdGrupo=acceso_objetos.IdGrupo
INNER JOIN
  usuarios ON
  usuarios.IdUsuario=usuarios_grupo.IdUsuario
WHERE
  IdUsuario=@IdUsuario AND
  NameObjeto=@NameObjeto

Ese select devuelve >0 si existe acceso al objeto o 0 si no.

Podes tener una clase con una funcion algo así:

Code: [Select]
bool CheckAccess(int IdUsuario,string NameObjeto) {
   /*** TODO: PREPARAR CONSULTA ***/
    If(sql.ExecuteScalar()> 0) {
      return true;
    } else {
      return false;
    }
}

Y en tu código de cada página podes tener algo como:

Code: [Select]
void OnPageLoad(...)
   If(Acceso.CheckAccess(Session['IdUsuario'],"menu_principal")) {
       // ejecutar codigo de inicializacion
   } else {
       // redireccionar a pagina de error o login
   }
}

La ventaja con este método es que podes luego definir los permisos como vos querras, es muy granular y fácil de implementar y lo podes "pegar" en los OnPageLoad que tengás.

Ahora... podes ir un poco más lejos y asociar los permisos a cada nombre de clase y cargar las clases correspondientes a la página en tu lista de objetos. Nada te limita a usarlo como querras incluso podes mostrar/ocultar opciones de menu dependiendo del grupo al que pertenescan solo colocando los "If" correspondientes. por ejemplo:

Grupo "Admin"
Objetos:
-->menu
-->menuadmin
-->agregar_usuarios
-->eliminar_usuarios
-->ver_usuarios

Grupo "Usuarios"
Objetos:
-->menu
-->ver_usuarios

Ejemplo:
Code: [Select]

<% If(Acceso.CheckAccess(Session['IdUsuario'],"menu")) { %>
<ul>
<% If(Acceso.CheckAccess(Session['IdUsuario'],"menuadmin")) { %>
  <li>Agregar usuarios</li>
  <li>Borrar usuarios</li>
<% } %>
  <li>ver Usuarios</li>
</ul>
<% } %>

Ojo que este método es plano, también pueden hacer un "arbol de permisos" que vaya heredando el acceso a objetos, pero para fines prácticos este método de acceso por grupo a nivel de objeto pienso que cubre la mayoría de necesidades de permisos.

Nota: Se que en .Net se pueden usar los RoleProvider, pero esto no es difícil de implementar se puede aplicar a muchos lenguajes y lo siento en lo personal más simple.


P.D.: Algunas recomendaciones extra:

1-La clase que verifica el acceso tiene que tener acceso a una conexión, en mi experiencia he encontrado que es mejor usar la misma conexión que está utilizando la página. Esto es para evitar que esté generando varias conexiones diferentes solo para chequear permisos.

2-Si no quieren estar haciendo un SQL para cada checkAccess, como en el caso que quieran habilitar/deshabilitar funciones en la página que se envía al cliente, pueden en la inicialización de la clase bajar todos los objetos a los que tiene permiso elusuario y guardarlo en memoria con un select como este:

Code: [Select]
SELECT DISTINCT
   NameObjeto
FROM  acceso_objetos
INNER JOIN
  usuarios_grupo ON
  usuarios_grupo.IdGrupo=acceso_objetos.IdGrupo
INNER JOIN
  usuarios ON
  usuarios.IdUsuario=usuarios_grupo.IdUsuario
WHERE
  IdUsuario=@IdUsuario
Nota: Se usa DISTINCT para que elimine nombres de objetos duplicados en caso que el usuario perteneciera a distintos grupos con acceso al mismo objeto. El resultado de esta consulta se puede guardar en un vector de strings.

Luego la función CheckAccess solo necesita el nombre del objeto:

Code: [Select]
bool CheckAccess(string NameObjeto) {
   foreach(string obj in userObjects) {
     if(obj.Equals(NameObjeto)) {
       return true;
     }
   }
   return false;
}

3-De nuevo repito, yo utilizo mucho este "sistema" de permisos porque es fácil de implementar y no requiere tocar archivos de configuración. Si hay algo que DETESTO con mi corazón es que para montar un sistema de autenticación y permisos sencillo se tenga que estar tocando 20 archivos diferentes o heredar 20 clases diferentes.

4-MUY, PERO MUY IMPORTANTE: Yo se que esto es básico, pero lo he visto tantas veces que vale la pena mencionarlo: El IdUsuario de sesión NUNCA PERO NUNCA tiene que ser establecido desde variables que vengan del cliente, SIEMPRE tiene que establecerse como variable de sesión en el lado del servidor luego de haber verificado las credenciales del usuario. Si  no lo hacen de esta manera corren el riesgo de que su aplicación sea vulnerable a ataques de escalado de privilegios.

5-Por qué me gusta esto más que las ACL. Simple, esto es una ACL pero sin complicaciones, la tabla de acceso_grupos es tu ACL pero es como la "lista de invitados" no está en la lista no entra. Además que una clase armada de esta manera te permite verificar el acceso ADENTRO DE la página. Hay algo que nunca me gustó de CakePHP por ejemplo es que sus ACL te obligan a que toda la vista esté asociada a una ACL. ¿Pero que tal si yo quiero que partes de la página se muestren a los admin y otras a los usuarios? Yo no voy a hacer una vista para un admin y una vista para un usuario normal cuando lo único que cambia es el botón. Si bien hay páginas en que queres tener un sistema como las ACL de CakePHP con permisos heredados y acceso por clases, acciones muchas veces el mismo diseño que tiene te restringe y sale incluso más flexible usando un sistema como este.

6-No todo es color de rosa XD si no tienen cuidado pueden tener 40,000 objetos que no saben nisiquiera que hacen. Una buena forma de verificar esto es que la aplicación "registre los objetos" es decir que si se hace un "CheckAccces" para un objeto que no existe este objeto se cree en la BD con la ref al codigo y luego se puede hacer un "cleanup" para ver si realmente se están utilizando todos los objetos definidos en la base.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: eduardo91 on August 01, 2012, 03:25:18 pm
Yo lo que considero más conveniente para estos casos es crear perfiles para usuarios. También una tabla en la bd con menús y una asociativa entre ambas. De la siguiente forma:

Menús
Id_Menu
Nombre
Url (aquí irá por ejemplo "~/Catalogos/Alumnos.aspx")

Usuarios
Id_Usuario
Id_Perfil
NombreUsuario
Identificador
Contraseña

Perfiles
Id_Perfil
NombrePerfil

PerfilesPermisos
Id_PerfilPermiso
Id_Menu
Id_Perfil
PermisoLectura
PermisoEscritura
PermisoEliminacion

Poniendo simplemente los campos básicos de la estructura...

Luego para no escribir en cada página el código para validar, en el "OnInit" (hacer override de la función) de la master podes validar si el Id_Perfil de alguna sesión está en en "AppRelativeVirtualPath" (Url) con un query relacionando las tablas, si no está usas Response.Redirect("~/Inicio.aspx")

Es una idea casi vaga pero acomodá las ideas y te queda una aplicación tentativamente segura...
Me parece interesante como lo planteas lo analizare.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: eduardo91 on August 01, 2012, 03:32:30 pm
Vaya mita la forma mas fácil es utilizar el Web.Config y CustomMemberShipProvider
Creas 2 carpetas, una donde vas a guardar las paginas para docentes y otra para las paginas d usuraio normal.
Luego desde el Web.Config, haces una denegación d acceso a la carpeta de docentes y especificas que usuarios van a tener acceso, y lo mismo para la otra carpeta.
Y listo, eso es todo.

Si quieres hacerlo ya con roles, tendrías que implementar además un CustomRoleProvider, entonces con ellos en el web.config en vez d conceder a usuario específicos, vas a conceder a usuario que estén en el rol X...

como ya tienes tu propia base de datos es obligación que hagas tus CustomMembershipProvider y CustomRoleProvider para que se adecue. A tu sistemas
La primera opción como seria, como se aria la denegación de usuarios desde el Web.Config tendria que usar membership que te crea la bd y luego configurarla como tu dices porque si es así es lo que quiero evitar que me cree una bd ya que yo tengo que implementar una propia.

No tenes por ahi algun link donde se explique lo de CustomRoleProvider
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: eduardo91 on August 01, 2012, 03:35:32 pm
Esto es algo que se necesita hacer muy frecuentemente en casi cualquier portal y usualmente no es tan sencillo como parece.

Yo generalmente utilizo permisos por grupo/objeto.

Cada usuario pertenece a un grupo y cada grupo tiene acceso a ciertos objetos. Al final intento crear una clase que verifique que el grupo tenga acceso al objeto especificado y en base a eso se permite el acceso.

Por ejemplo:

Tabla usuarios:
IdUsuario (PK)

Tabla grupos:
IdGrupo (PK)

Tabla usuarios_grupo
IdGrupo (PK)(FK)
IdUsuario (PK)(FK)

Tabla Objetos:
IdObjeto (PK)
NameObjeto (UNIQUE idx)

Tabla Acceso_Objetos
IdGrupo (PK)(FK)
IdObjeto (PK)(FK)

Tendrías que crear una clase que tome el usuario y ejecute un código como este:

Code: [Select]

SELECT
  COUNT(*) AS ACCESO_OBJETOS
FROM  acceso_objetos
INNER JOIN
  usuarios_grupo ON
  usuarios_grupo.IdGrupo=acceso_objetos.IdGrupo
INNER JOIN
  usuarios ON
  usuarios.IdUsuario=usuarios_grupo.IdUsuario
WHERE
  IdUsuario=@IdUsuario AND
  NameObjeto=@NameObjeto

Ese select devuelve >0 si existe acceso al objeto o 0 si no.

Podes tener una clase con una funcion algo así:

Code: [Select]
bool CheckAccess(int IdUsuario,string NameObjeto) {
   /*** TODO: PREPARAR CONSULTA ***/
    If(sql.ExecuteScalar()> 0) {
      return true;
    } else {
      return false;
    }
}

Y en tu código de cada página podes tener algo como:

Code: [Select]
void OnPageLoad(...)
   If(Acceso.CheckAccess(Session['IdUsuario'],"menu_principal")) {
       // ejecutar codigo de inicializacion
   } else {
       // redireccionar a pagina de error o login
   }
}

La ventaja con este método es que podes luego definir los permisos como vos querras, es muy granular y fácil de implementar y lo podes "pegar" en los OnPageLoad que tengás.

Ahora... podes ir un poco más lejos y asociar los permisos a cada nombre de clase y cargar las clases correspondientes a la página en tu lista de objetos. Nada te limita a usarlo como querras incluso podes mostrar/ocultar opciones de menu dependiendo del grupo al que pertenescan solo colocando los "If" correspondientes. por ejemplo:

Grupo "Admin"
Objetos:
-->menu
-->menuadmin
-->agregar_usuarios
-->eliminar_usuarios
-->ver_usuarios

Grupo "Usuarios"
Objetos:
-->menu
-->ver_usuarios

Ejemplo:
Code: [Select]

<% If(Acceso.CheckAccess(Session['IdUsuario'],"menu")) { %>
<ul>
<% If(Acceso.CheckAccess(Session['IdUsuario'],"menuadmin")) { %>
  <li>Agregar usuarios</li>
  <li>Borrar usuarios</li>
<% } %>
  <li>ver Usuarios</li>
</ul>
<% } %>

Ojo que este método es plano, también pueden hacer un "arbol de permisos" que vaya heredando el acceso a objetos, pero para fines prácticos este método de acceso por grupo a nivel de objeto pienso que cubre la mayoría de necesidades de permisos.

Nota: Se que en .Net se pueden usar los RoleProvider, pero esto no es difícil de implementar se puede aplicar a muchos lenguajes y lo siento en lo personal más simple.


P.D.: Algunas recomendaciones extra:

1-La clase que verifica el acceso tiene que tener acceso a una conexión, en mi experiencia he encontrado que es mejor usar la misma conexión que está utilizando la página. Esto es para evitar que esté generando varias conexiones diferentes solo para chequear permisos.

2-Si no quieren estar haciendo un SQL para cada checkAccess, como en el caso que quieran habilitar/deshabilitar funciones en la página que se envía al cliente, pueden en la inicialización de la clase bajar todos los objetos a los que tiene permiso elusuario y guardarlo en memoria con un select como este:

Code: [Select]
SELECT DISTINCT
   NameObjeto
FROM  acceso_objetos
INNER JOIN
  usuarios_grupo ON
  usuarios_grupo.IdGrupo=acceso_objetos.IdGrupo
INNER JOIN
  usuarios ON
  usuarios.IdUsuario=usuarios_grupo.IdUsuario
WHERE
  IdUsuario=@IdUsuario
Nota: Se usa DISTINCT para que elimine nombres de objetos duplicados en caso que el usuario perteneciera a distintos grupos con acceso al mismo objeto. El resultado de esta consulta se puede guardar en un vector de strings.

Luego la función CheckAccess solo necesita el nombre del objeto:

Code: [Select]
bool CheckAccess(string NameObjeto) {
   foreach(string obj in userObjects) {
     if(obj.Equals(NameObjeto)) {
       return true;
     }
   }
   return false;
}

3-De nuevo repito, yo utilizo mucho este "sistema" de permisos porque es fácil de implementar y no requiere tocar archivos de configuración. Si hay algo que DETESTO con mi corazón es que para montar un sistema de autenticación y permisos sencillo se tenga que estar tocando 20 archivos diferentes o heredar 20 clases diferentes.

4-MUY, PERO MUY IMPORTANTE: Yo se que esto es básico, pero lo he visto tantas veces que vale la pena mencionarlo: El IdUsuario de sesión NUNCA PERO NUNCA tiene que ser establecido desde variables que vengan del cliente, SIEMPRE tiene que establecerse como variable de sesión en el lado del servidor luego de haber verificado las credenciales del usuario. Si  no lo hacen de esta manera corren el riesgo de que su aplicación sea vulnerable a ataques de escalado de privilegios.

5-Por qué me gusta esto más que las ACL. Simple, esto es una ACL pero sin complicaciones, la tabla de acceso_grupos es tu ACL pero es como la "lista de invitados" no está en la lista no entra. Además que una clase armada de esta manera te permite verificar el acceso ADENTRO DE la página. Hay algo que nunca me gustó de CakePHP por ejemplo es que sus ACL te obligan a que toda la vista esté asociada a una ACL. ¿Pero que tal si yo quiero que partes de la página se muestren a los admin y otras a los usuarios? Yo no voy a hacer una vista para un admin y una vista para un usuario normal cuando lo único que cambia es el botón. Si bien hay páginas en que queres tener un sistema como las ACL de CakePHP con permisos heredados y acceso por clases, acciones muchas veces el mismo diseño que tiene te restringe y sale incluso más flexible usando un sistema como este.

6-No todo es color de rosa XD si no tienen cuidado pueden tener 40,000 objetos que no saben nisiquiera que hacen. Una buena forma de verificar esto es que la aplicación "registre los objetos" es decir que si se hace un "CheckAccces" para un objeto que no existe este objeto se cree en la BD con la ref al codigo y luego se puede hacer un "cleanup" para ver si realmente se están utilizando todos los objetos definidos en la base.
Si yo pensé que era sencillo pero me estoy quebrando la cabeza para implementarlo, analizare lo que me propones
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: mxgxw on August 01, 2012, 03:51:54 pm
La primera opción como seria, como se aria la denegación de usuarios desde el Web.Config tendria que usar membership que te crea la bd y luego configurarla como tu dices porque si es así es lo que quiero evitar que me cree una bd ya que yo tengo que implementar una propia.

No tenes por ahi algun link donde se explique lo de CustomRoleProvider


Los MembershipProvider y RoleProvider funcionan de manera similar a lo que te puse. Sin embargo muchas veces termino haciendolo como te expliqué porque la codificación es cientos de veces más sencilla.

Para mi siempre ha sido un poco contradictorio que tengas que modificar el web.config, luego tenes que armar tu clase para el Membership Provider y Role Provider para algo tan simple como: ¿Quiero saber si X usuario tiene acceso a Y objeto?

Yo se que son poderosos si y son "estándar" en microsoft, pero al menos yo prefiero usar un diseño simple, fácil de migrar a otros lenguajes a estar amarrado exclusivamente con la manera de pensar de "microsoft".
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: eduardo91 on August 01, 2012, 04:46:02 pm
Los MembershipProvider y RoleProvider funcionan de manera similar a lo que te puse. Sin embargo muchas veces termino haciendolo como te expliqué porque la codificación es cientos de veces más sencilla.

Para mi siempre ha sido un poco contradictorio que tengas que modificar el web.config, luego tenes que armar tu clase para el Membership Provider y Role Provider para algo tan simple como: ¿Quiero saber si X usuario tiene acceso a Y objeto?

Yo se que son poderosos si y son "estándar" en microsoft, pero al menos yo prefiero usar un diseño simple, fácil de migrar a otros lenguajes a estar amarrado exclusivamente con la manera de pensar de "microsoft".
Ok entonces tratare de aplicar la forma como tu me lo planteas, modificare la bd para agregar las nuevas tablas  y empezare a implementarlo, si tienes algún link sobre algún ejemplo donde implementen la forma en que lo planteas me seria de gran ayuda.

Saludos.

Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: Juancho on August 01, 2012, 09:42:10 pm
Ok mira, como dice @mxgxw, utilizando el MemberShipProvider y RoleProvider es utilizar las clases que microsoft pone a disposicion de los desarrolladores para que pueden implementar su modelo de roles, usuarios (y sesiones). Alli realmenta queda a opcion tuya si lo utilizas y haces los pasos necesarios para implementarlo, o simplemente puedes pensar una manera de validar a los usuarios, ya depende de ti, asi como la solucion que te propone mxgxw para que puedas implementar los usuarios y roles.

Bueno, por si t sirve, voy a colocar lo que tendrias que configurar para seguir el modelo de Microsoft (utilizando MembershipProvider y RoleProvider):

Vamos a utilizar las 3 primeras tablas tablas con los campos basicos que puso mxgxw:
Code: [Select]
Tabla usuarios:
IdUsuario (PK)

Tabla grupos:
IdGrupo (PK)

Tabla usuarios_grupo
IdGrupo (PK)(FK)
IdUsuario (PK)(FK)

Serian los usuarios con el Rol (o grupo) al que pertenecen.

Bueno como te dije antes, en tu proyecto puedes crear 2 carpetas: la primera para "Docentes", y la segunda "Normal".
Dentro de cada una de tus carpetas vas a poner las paginas que tenga acceso el grupo de usuarios.

Una vez tienes hecho, hay que configurar el acceso a las carpetas a partir del Web.Config:
Code: [Select]
<location path="Alumnos">
    <system.web>
      <authorization>
        <allow roles="ALU" />
      </authorization>
    </system.web>
  </location>
<location path="Alumnos">
    <system.web>
      <authorization>
        <allow roles="PRF" />
      </authorization>
    </system.web>
  </location>

Ahora debes de implementar el MembershipProvider que sera el encargado de validar el usuario, y el RoleProvider que se encargara de manejar los roles del usuario.
Primero, hay que implementar el MembershipProvider: Lo unico que itienes que hacer es crear una nueva clase en tu proyecto, y en esa nueva clase que has creado, tienes que hacer que herede de la clase MembershipProvider, cuando la heredes, apareceran un monton de metodos (esto es xq es una clase abstracta), y el unico metodo que nos interesa ahorita es el metodo ValidateUser:
Apues en este metodo vas a escribir la logica para validar al usuario, por ejemplo:
Code: [Select]
Public Overrides Function ValidateUser(username As String, password As String) As Boolean
   'Aqui vas a establecer toda tu logica para validar las credenciales de usuario, si utilizas, LINQ, EF, ADO.NET para ir a la BD y consultar si es valido
   'lo que tienes que regresar es un TRUE si es valido, y un FALSE si no es correcto el login.
End Function

Una vez tienes el metodo completo, los demas metodos los podes ignorar (al menos en este caso), y ahora hay que configurar los metodos de los roles y que funciones todo correctamente.

Ahora, tienes que crear una nueva clase, y en esa clase vas a heredar de la clase RoleProvider y de nuevo te van aparecer un monton de metodos, los que nos interesaran seran los siguientes:
Code: [Select]
Public Overrides Function IsUserInRole(username As String, roleName As String) As Boolean
   'Creas la logica para ir a comprobar a tu BD si el usuario se encuentra en el rol o no y de nuevo regresas un TRUE o FALSE
End Function

Public Overrides Function GetRolesForUser(username As String) As String()
    'Creas la logica para ir a extraer a la BD los roles a los que pertenece el usuario, lo que tienes q regresar en un Array de tipo String, donde esten
    'contenidos todos los roles a los que pertenece el usuario
End Function

Una vez ya tienes los metodos para el servidor, solo te faltaria agregar tu MembershipProvider y tu RoleProvider al archivo del Web.Config:
Code: [Select]
<system.web>
   <membership defaultProvider="CustomMP">
      <providers>
        <clear />
        <add name="CustomMP" type="Aqui pones el nombre de la clase que creastes de tu proyecto con todo y su NameSpace EJ: Proyecto.ClaseMembership " />
      </providers>
    </membership>
    <roleManager defaultProvider="CustomRPr" enabled="true" cacheRolesInCookie="true">
      <providers>
        <clear />
        <add name="CustomRP" type="Aqui pones el nombre de la clase que creastes de tu proyecto con todo y su NameSpace EJ: Proyecto.ClaseRol" />
      </providers>
    </roleManager>
</system.web>

Y eso es todo lo que tienes que hacer y ya lo tienes configurado, ASP.NET se encargara de ver los permisos delo usuario que entre a tu sitio web si tiene permisos, ya no haces nada mas..

Esta es la forma que Microsoft recomienda para sus sitios web, utilizando las 2 clases con que viene ASP, pero si tu quieres hacer una Autorizacion propia puedes hacerlo, yo te pongo el ejemplo de como se hace normalmente en ASP.NET.

Si quiere mayor informacion para utilizar las etiquetas location en el Web.Config, puedes ver un link del guille, o en MSDN hay muchos ejemplos de como validar permisos a carpetas o paginas especificas.
http://www.elguille.info/net/aspnet/indicar_elementos_publicos_privados.htm (http://www.elguille.info/net/aspnet/indicar_elementos_publicos_privados.htm)

Bueno, aunque te soy sincero, nunca he desarrollado un sitio en ASP.NET, pero cuando estaba aprendiendo el modo de autenticacion para ASP.NET MVC explicaban la diferencia de como se autenticaba en un sitio ASP.NET y como cambiaba para un sitio ASP.NET MVC, asi que, asi aprendi... jajaja xD
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: mxgxw on August 02, 2012, 09:00:25 am
Ok mira, como dice @mxgxw, utilizando el MemberShipProvider y RoleProvider es utilizar las clases que microsoft pone a disposicion de los desarrolladores para que pueden implementar su modelo de roles, usuarios (y sesiones). Alli realmenta queda a opcion tuya si lo utilizas y haces los pasos necesarios para implementarlo, o simplemente puedes pensar una manera de validar a los usuarios, ya depende de ti, asi como la solucion que te propone mxgxw para que puedas implementar los usuarios y roles.

Bueno, por si t sirve, voy a colocar lo que tendrias que configurar para seguir el modelo de Microsoft (utilizando MembershipProvider y RoleProvider):

Vamos a utilizar las 3 primeras tablas tablas con los campos basicos que puso mxgxw:
Code: [Select]
Tabla usuarios:
IdUsuario (PK)

Tabla grupos:
IdGrupo (PK)

Tabla usuarios_grupo
IdGrupo (PK)(FK)
IdUsuario (PK)(FK)

Serian los usuarios con el Rol (o grupo) al que pertenecen.

Bueno como te dije antes, en tu proyecto puedes crear 2 carpetas: la primera para "Docentes", y la segunda "Normal".
Dentro de cada una de tus carpetas vas a poner las paginas que tenga acceso el grupo de usuarios.

Una vez tienes hecho, hay que configurar el acceso a las carpetas a partir del Web.Config:
Code: [Select]
<location path="Alumnos">
    <system.web>
      <authorization>
        <allow roles="ALU" />
      </authorization>
    </system.web>
  </location>
<location path="Alumnos">
    <system.web>
      <authorization>
        <allow roles="PRF" />
      </authorization>
    </system.web>
  </location>

Ahora debes de implementar el MembershipProvider que sera el encargado de validar el usuario, y el RoleProvider que se encargara de manejar los roles del usuario.
Primero, hay que implementar el MembershipProvider: Lo unico que itienes que hacer es crear una nueva clase en tu proyecto, y en esa nueva clase que has creado, tienes que hacer que herede de la clase MembershipProvider, cuando la heredes, apareceran un monton de metodos (esto es xq es una clase abstracta), y el unico metodo que nos interesa ahorita es el metodo ValidateUser:
Apues en este metodo vas a escribir la logica para validar al usuario, por ejemplo:
Code: [Select]
Public Overrides Function ValidateUser(username As String, password As String) As Boolean
   'Aqui vas a establecer toda tu logica para validar las credenciales de usuario, si utilizas, LINQ, EF, ADO.NET para ir a la BD y consultar si es valido
   'lo que tienes que regresar es un TRUE si es valido, y un FALSE si no es correcto el login.
End Function

Una vez tienes el metodo completo, los demas metodos los podes ignorar (al menos en este caso), y ahora hay que configurar los metodos de los roles y que funciones todo correctamente.

Ahora, tienes que crear una nueva clase, y en esa clase vas a heredar de la clase RoleProvider y de nuevo te van aparecer un monton de metodos, los que nos interesaran seran los siguientes:
Code: [Select]
Public Overrides Function IsUserInRole(username As String, roleName As String) As Boolean
   'Creas la logica para ir a comprobar a tu BD si el usuario se encuentra en el rol o no y de nuevo regresas un TRUE o FALSE
End Function

Public Overrides Function GetRolesForUser(username As String) As String()
    'Creas la logica para ir a extraer a la BD los roles a los que pertenece el usuario, lo que tienes q regresar en un Array de tipo String, donde esten
    'contenidos todos los roles a los que pertenece el usuario
End Function

Una vez ya tienes los metodos para el servidor, solo te faltaria agregar tu MembershipProvider y tu RoleProvider al archivo del Web.Config:
Code: [Select]
<system.web>
   <membership defaultProvider="CustomMP">
      <providers>
        <clear />
        <add name="CustomMP" type="Aqui pones el nombre de la clase que creastes de tu proyecto con todo y su NameSpace EJ: Proyecto.ClaseMembership " />
      </providers>
    </membership>
    <roleManager defaultProvider="CustomRPr" enabled="true" cacheRolesInCookie="true">
      <providers>
        <clear />
        <add name="CustomRP" type="Aqui pones el nombre de la clase que creastes de tu proyecto con todo y su NameSpace EJ: Proyecto.ClaseRol" />
      </providers>
    </roleManager>
</system.web>

Y eso es todo lo que tienes que hacer y ya lo tienes configurado, ASP.NET se encargara de ver los permisos delo usuario que entre a tu sitio web si tiene permisos, ya no haces nada mas..

Esta es la forma que Microsoft recomienda para sus sitios web, utilizando las 2 clases con que viene ASP, pero si tu quieres hacer una Autorizacion propia puedes hacerlo, yo te pongo el ejemplo de como se hace normalmente en ASP.NET.

Si quiere mayor informacion para utilizar las etiquetas location en el Web.Config, puedes ver un link del guille, o en MSDN hay muchos ejemplos de como validar permisos a carpetas o paginas especificas.
http://www.elguille.info/net/aspnet/indicar_elementos_publicos_privados.htm (http://www.elguille.info/net/aspnet/indicar_elementos_publicos_privados.htm)

Bueno, aunque te soy sincero, nunca he desarrollado un sitio en ASP.NET, pero cuando estaba aprendiendo el modo de autenticacion para ASP.NET MVC explicaban la diferencia de como se autenticaba en un sitio ASP.NET y como cambiaba para un sitio ASP.NET MVC, asi que, asi aprendi... jajaja xD

Realmente el modelo de "Membresias" y "Roles" para ASP.NET puede utilizarse tal cual o puede modificarse para que funcione así como el ejemplo que le daba al comuno.

Realmente generalizando un poco más vos podes asociar los usuarios con los grupos (perfiles o roles como les querras llamar) de la mejor forma que se adapte a tu aplicación...

Pensando un poco en voz alta a la hora de autenticar y definir permisos tenes varias opciones (de la más simple a la más compleja):

1-Autenticación simple que solo verifica credenciales, no hace diferenciación de grupos y/o permisos.

2-Usuarios y Grupos, como se asocien los usuarios al grupo depende de tu implementación. Podrías tener un usuario asociado a un grupo en particular o un usuario asociado a varios grupos o perfiles (como mi ejemplo).

3-Para MVC podes tener ACLs a nivel de Controlador/Acción así como CakePHP. Este utiliza el concepto tradicional de usuario/grupo y define listas de control de acceso en base a las acciones del controlador. Muy útil si utilizas el paradigma de diseño MVC, pero la limitante como puse anteriormente es que no podes hacer una diferenciación específica de permisos dentro de la vista, al menos no sin romper el paradigma de diseño MVC. Con lo que terminas creando dos acciones diferentes para dos "roles" diferentes o rompiendo el MVC. No sé sinceramente que utiliza .NET para ACLs cuando usas MVC, ¿tal vez nos podes explicar?

4-Todos los modelos de autenticación/permisos basados en directorios (estilo LDAP), este a mi manera de ver es MUY complejo de implementar, pero realmente creo que es de lo más flexible que hay en tanto la información de autenticación como la de los permisos para cada objeto pueden almacenarse en el directorio y administrarse de manera centralizada. Siempre quise montar una aplicación que usara LDAP para el acceso a sus usuarios, lástimosamente no es algo "muy popular" jejejejeje Los que trabajan mucho con el Active Directory esto es casi una bendición caida del cielo porque pueden controlar el acceso a las aplicaciones desde su Domain Controller :) Ojo que estoy hablando de permisos y no solo de autenticar al usuario, a la fecha al menos en lo que he trabajado no he visto ninguna aplicación que saque los permisos del directorio, usualmente solo verifican que el usuario se válido y los diferentes permisos se almacenan a nivel de BD para la aplicación en específico.

La solución que le propuse al compañero es una especie de híbrido entre 2 y 3 solo que en vez de obtener permisos por vista se obtienen permisos a nivel de objeto definido por el desarrollador.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: Juancho on August 02, 2012, 09:36:25 am
Realmente el modelo de "Membresias" y "Roles" para ASP.NET puede utilizarse tal cual o puede modificarse para que funcione así como el ejemplo que le daba al comuno.

Es que si utilizas el modelo tal cual que trae ASP.NET, tienes que utilizar a fuerza el modelo integrado de seguridad de ASP, donde vas creando los usuarios, roles (grupos, perfiles, etc.. jajaj xD) a partir de la pantalla de configuracion del server ASP (se me ha olvidado como se llama), asi que como el compañero habia mencionado que ya tenia en su base de datos los usuarios y roles era para enseñar utilizando nuestros propios MemberShipProvider y RoleProvider sin utilizar la seguridad integrada de asp.net (era similar a lo que tu habias puesto solo que desde el web.config) y como ASP.NET se puede encargar de la autentificacion y roles en una aplicacion por si solo definiendo los metodos necesarios.

1-Autenticación simple que solo verifica credenciales, no hace diferenciación de grupos y/o permisos.

2-Usuarios y Grupos, como se asocien los usuarios al grupo depende de tu implementación. Podrías tener un usuario asociado a un grupo en particular o un usuario asociado a varios grupos o perfiles (como mi ejemplo).

3-Para MVC podes tener ACLs a nivel de Controlador/Acción así como CakePHP. Este utiliza el concepto tradicional de usuario/grupo y define listas de control de acceso en base a las acciones del controlador. Muy útil si utilizas el paradigma de diseño MVC, pero la limitante como puse anteriormente es que no podes hacer una diferenciación específica de permisos dentro de la vista, al menos no sin romper el paradigma de diseño MVC. Con lo que terminas creando dos acciones diferentes para dos "roles" diferentes o rompiendo el MVC. No sé sinceramente que utiliza .NET para ACLs cuando usas MVC, ¿tal vez nos podes explicar?

4-Todos los modelos de autenticación/permisos basados en directorios (estilo LDAP), este a mi manera de ver es MUY complejo de implementar, pero realmente creo que es de lo más flexible que hay en tanto la información de autenticación como la de los permisos para cada objeto pueden almacenarse en el directorio y administrarse de manera centralizada. Siempre quise montar una aplicación que usara LDAP para el acceso a sus usuarios, lástimosamente no es algo "muy popular" jejejejeje Los que trabajan mucho con el Active Directory esto es casi una bendición caida del cielo porque pueden controlar el acceso a las aplicaciones desde su Domain Controller :) Ojo que estoy hablando de permisos y no solo de autenticar al usuario, a la fecha al menos en lo que he trabajado no he visto ninguna aplicación que saque los permisos del directorio, usualmente solo verifican que el usuario se válido y los diferentes permisos se almacenan a nivel de BD para la aplicación en específico.

Amen a esto...

3-Para MVC podes tener ACLs a nivel de Controlador/Acción así como CakePHP. Este utiliza el concepto tradicional de usuario/grupo y define listas de control de acceso en base a las acciones del controlador. Muy útil si utilizas el paradigma de diseño MVC, pero la limitante como puse anteriormente es que no podes hacer una diferenciación específica de permisos dentro de la vista, al menos no sin romper el paradigma de diseño MVC. Con lo que terminas creando dos acciones diferentes para dos "roles" diferentes o rompiendo el MVC. No sé sinceramente que utiliza .NET para ACLs cuando usas MVC, ¿tal vez nos podes explicar?

Vaya con respecto al ASP.NET MVC, y su autorizacion de usuario/grupo, perfectamente se definen igual los MembershipProvider y RoleProvider para administrar los grupos/usuario en la aplicacion, solo que ahora como no son "paginas" sino que es metodo/controlador, entonces se cuenta con un atributo llamado AuthorizeAttribute, este lo vas aplicando a cada uno de los metodos del controlador o al controlador completo para la autorizacion ya sea de un usuario especifico o un rol especifico (si en toda la aplicacion queremos que los usuarios se identifiquen mejor aplico un FiltroGlobal a toda la aplicacion y que m restringa toda la aplicacion la autorizacion).
Y bueno, con respecto de crear 2 metodos para un distinto rol, si en ASP.NET utilizas el Membership y autentificacion por una Cookie, en el metodo podrias identificar que usuario esta logeado y asi mostrar una Vista (o vista parcial) dependiendo del usuario. O hasta podrias pasar el Grupo(o rol) del usuario identificado por medio de la coleccion de objetos que recibe la vista (ViewBag). Y ya en tu vista dependiendo del Rol que se pasa en el ViewBag, puedes mostrar o decirle al Motor que lo renderize o no
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: mxgxw on August 02, 2012, 10:08:47 am
Es que si utilizas el modelo tal cual que trae ASP.NET, tienes que utilizar a fuerza el modelo integrado de seguridad de ASP, donde vas creando los usuarios, roles (grupos, perfiles, etc.. jajaj xD) a partir de la pantalla de configuracion del server ASP (se me ha olvidado como se llama), asi que como el compañero habia mencionado que ya tenia en su base de datos los usuarios y roles era para enseñar utilizando nuestros propios MemberShipProvider y RoleProvider sin utilizar la seguridad integrada de asp.net (era similar a lo que tu habias puesto solo que desde el web.config) y como ASP.NET se puede encargar de la autentificacion y roles en una aplicacion por si solo definiendo los metodos necesarios.

Amen a esto...

Vaya con respecto al ASP.NET MVC, y su autorizacion de usuario/grupo, perfectamente se definen igual los MembershipProvider y RoleProvider para administrar los grupos/usuario en la aplicacion, solo que ahora como no son "paginas" sino que es metodo/controlador, entonces se cuenta con un atributo llamado AuthorizeAttribute, este lo vas aplicando a cada uno de los metodos del controlador o al controlador completo para la autorizacion ya sea de un usuario especifico o un rol especifico (si en toda la aplicacion queremos que los usuarios se identifiquen mejor aplico un FiltroGlobal a toda la aplicacion y que m restringa toda la aplicacion la autorizacion).
Y bueno, con respecto de crear 2 metodos para un distinto rol, si en ASP.NET utilizas el Membership y autentificacion por una Cookie, en el metodo podrias identificar que usuario esta logeado y asi mostrar una Vista (o vista parcial) dependiendo del usuario. O hasta podrias pasar el Grupo(o rol) del usuario identificado por medio de la coleccion de objetos que recibe la vista (ViewBag). Y ya en tu vista dependiendo del Rol que se pasa en el ViewBag, puedes mostrar o decirle al Motor que lo renderize o no


xD Ah bueno, lo mismo he hecho en CakePHP para no tener que hacer dos "vistas" pasar el nombre del grupo como variable a la vista. Pero igual no me hace dejar de sentir "sucio" pensar que estoy teniendo que verificar a que rol pertenece, el problema que tengo con esa "filosofía de permisos" es que luego: ¿Como cambio el permiso de acceso al rol? R/ Tengo que ir al código y modificarlo. Eso simplemente no me gusta yo quería un sistema de permisos que almacenara todas las "unidades" posibles dentro de la DB y dentro de la db pudiera asignar o eliminar acceso a cada una de estas "unidades".

Ojo que esa unidad puede ser una vista, un controlador completo, una funcion o incluso un segmento de código dentro de una función. Llegar a ese nivel de detalle simplemente no es posible utilizando las ACLs o los RoleProviders. En mi mente tengo muy aferrada la idea que la aplicación es un conjunto de objetos y los roles tienen accesos a diferentes objetos, en ningun momento el código debería decidir que roles tienen acceso a que funcion.

¿Alguno me dira? Pero mx.... podes definir cuantos roles querras y verificar en la app en base a roles. Y les digo NO, porque los roles los define el administrador del sistema NO EL DESAROLLADOR, sin embargo los objetos del sistema si los define el desarrollador, así que el desarrollador debería en su sótano definir cuantos objetos diferentes fueran necesarios y el administrador del sistema es quien tiene que decidir en base a los perfiles de usuarios (roles o grupos) a que objetos tienen acceso.

Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: Juancho on August 02, 2012, 10:28:43 am
xD Ah bueno, lo mismo he hecho en CakePHP para no tener que hacer dos "vistas" pasar el nombre del grupo como variable a la vista. Pero igual no me hace dejar de sentir "sucio" pensar que estoy teniendo que verificar a que rol pertenece, el problema que tengo con esa "filosofía de permisos" es que luego: ¿Como cambio el permiso de acceso al rol? R/ Tengo que ir al código y modificarlo. Eso simplemente no me gusta yo quería un sistema de permisos que almacenara todas las "unidades" posibles dentro de la DB y dentro de la db pudiera asignar o eliminar acceso a cada una de estas "unidades".

Ojo que esa unidad puede ser una vista, un controlador completo, una funcion o incluso un segmento de código dentro de una función. Llegar a ese nivel de detalle simplemente no es posible utilizando las ACLs o los RoleProviders. En mi mente tengo muy aferrada la idea que la aplicación es un conjunto de objetos y los roles tienen accesos a diferentes objetos, en ningun momento el código debería decidir que roles tienen acceso a que funcion.

Bueno, si eso es lo que deseas hacer, creo q si habria una forma parcial de implementarlo en ASP.NET MVC, por ejemplo: Asi como tu dices, se podrian tener unas tablas en la Base de Datos donde almacenemos el Controlador y Metodos (y quizas codigo dentro de una vista). Vaya podrias guardar los nombres de los objetos en la BD (Controlador, Metodos, etc) y a partir de la clase AuthorizeAtribute, crear una clase derivada y sobreescribir el metodo OnAuthorization y colocar la logica para ir a comprobar a la Base de datos si el usuario que se encuentra accediendo al Controlador o Metodo tiene acceso al objeto, de esta manera podrias controlar todo desde la base de datos, asi que todo podrias manejarlo desde la base de datos. Lo que no recuerdo bien es si desde el  OnAuthorization puedes tener acceso al ViewBag del metodo al que se esta intentando acceder (ojo si ha sido metodo no un controlador), porque si fuera asi, podrias pasar en el ViewBag ese codigo a la vista cuando es X rol/usuario.

Muy interesante tu modelo propuesto para no tener que ir a tocar el codigo fuente, y estar cambiando los roles. Aunque si pudieras pasar codigo a la vista, en todo caso creo q podrias pasar el codigo HTML (guardado en la BD) y luego rendelizarlo en la vista el codigo que se ha pasado en la variable.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: mxgxw on August 02, 2012, 10:36:36 am
Bueno, si eso es lo que deseas hacer, creo q si habria una forma parcial de implementarlo en ASP.NET MVC, por ejemplo: Asi como tu dices, se podrian tener unas tablas en la Base de Datos donde almacenemos el Controlador y Metodos (y quizas codigo dentro de una vista). Vaya podrias guardar los nombres de los objetos en la BD (Controlador, Metodos, etc) y a partir de la clase AuthorizeAtribute, crear una clase derivada y sobreescribir el metodo OnAuthorization y colocar la logica para ir a comprobar a la Base de datos si el usuario que se encuentra accediendo al Controlador o Metodo tiene acceso al objeto, de esta manera podrias controlar todo desde la base de datos, asi que todo podrias manejarlo desde la base de datos. Lo que no recuerdo bien es si desde el  OnAuthorization puedes tener acceso al ViewBag del metodo al que se esta intentando acceder (ojo si ha sido metodo no un controlador), porque si fuera asi, podrias pasar en el ViewBag ese codigo a la vista cuando es X rol/usuario.

Muy interesante tu modelo propuesto para no tener que ir a tocar el codigo fuente, y estar cambiando los roles. Aunque si pudieras pasar codigo a la vista, en todo caso creo q podrias pasar el codigo HTML (guardado en la BD) y luego rendelizarlo en la vista el codigo que se ha pasado en la variable.

Pero siempre "aclaro", yo lo hago así porque así me gusta, me siento cómodo y me ha funcionado. Realmente depende mucho de la aplicación que estemos desarrollando y posiblemente mi solución sea un overkill para algunos casos. Hay que recordar que al final nos pagan para buscar la solución más adecuada utilizando los recursos que tengamos disponibles jeje :)
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: Juancho on August 02, 2012, 10:58:20 am
Pero siempre "aclaro", yo lo hago así porque así me gusta, me siento cómodo y me ha funcionado. Realmente depende mucho de la aplicación que estemos desarrollando y posiblemente mi solución sea un overkill para algunos casos. Hay que recordar que al final nos pagan para buscar la solución más adecuada utilizando los recursos que tengamos disponibles jeje :)

jajajaj toda la razon, y en el menor tiempo posible tambien.. jajaja xD
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: tekun on August 02, 2012, 12:28:19 pm
Pero siempre "aclaro", yo lo hago así porque así me gusta, me siento cómodo y me ha funcionado. Realmente depende mucho de la aplicación que estemos desarrollando y posiblemente mi solución sea un overkill para algunos casos. Hay que recordar que al final nos pagan para buscar la solución más adecuada utilizando los recursos que tengamos disponibles jeje :)

yo no se si he entendido mal todas las respuestas que han puesto, pero mxgxw, juancho y compañia.. han hablado de presentar una página si hay una tabla que relacione un usuario a esa pagina/objeto (como le llama mx)

pero no he visto que hablen de ACL en los objetos de la base de datos.... será que sólo yo trabajo mis accesos a formularios, en conjunto con mis accesos a las tablas/vistas/funciones/sequences de la base de datos ?

para los proyectos que han echo  mx o juancho, si yo logro conectarme de una aplicación distinta a la que ellos hayan creado, hablemos de una aplicación destok o otro proyecto asp, puedo ver TOOODAS las tablas y Modificar TOOODO el contenido de las mismas, porque con mi usuario tengo acceso a TOOODO en la db..... o me equivoco?

obviamente, como dice mx, cada quién trabaja a como de el tiempo y muchas veces, se heredan proyectos que cambiarlos es un huevo hay que seguir igual de patiadito... y otras veces es cuestion de "tiempo" para poder implementar el deber ser...
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: mxgxw on August 02, 2012, 12:59:57 pm
yo no se si he entendido mal todas las respuestas que han puesto, pero mxgxw, juancho y compañia.. han hablado de presentar una página si hay una tabla que relacione un usuario a esa pagina/objeto (como le llama mx)

pero no he visto que hablen de ACL en los objetos de la base de datos.... será que sólo yo trabajo mis accesos a formularios, en conjunto con mis accesos a las tablas/vistas/funciones/sequences de la base de datos ?

para los proyectos que han echo  mx o juancho, si yo logro conectarme de una aplicación distinta a la que ellos hayan creado, hablemos de una aplicación destok o otro proyecto asp, puedo ver TOOODAS las tablas y Modificar TOOODO el contenido de las mismas, porque con mi usuario tengo acceso a TOOODO en la db..... o me equivoco?

obviamente, como dice mx, cada quién trabaja a como de el tiempo y muchas veces, se heredan proyectos que cambiarlos es un huevo hay que seguir igual de patiadito... y otras veces es cuestion de "tiempo" para poder implementar el deber ser...

Tekun, realmente vos decis algo muy importante. Lo que pasa es que usualmente las aplicaciones web utilizan un usuario de la aplicación para conectarse al gestor de bases de datos. Por ejemplo en .NET utilizas la autenticación de windows para pegarte a la base de datos.

Ahora... En un mundo ideal, el mismo usuario de tu aplicación web debería de tener un usuario asociado a la BD, de tal manera que podás definir acceso a tablas/vistas/SP en base a las credenciales del usuario. El problema es que eso rara vez se puede hacer de esa manera en aplicaciones web.

O incluso... ¿Decime cuantos DBA te dan acceso completo a la BD para que podas pegar los usuarios de tu portal directamente al gestor de la base de datos? NADIE, aunque idealmente tanto tu aplicacion como la DB deberían autenticar usuarios utilizando algún servicio de credenciales externo, por ejemplo autenticando contra el AD. Ojo que eso es lo "ideal".

Lo que se termina haciendo con aplicaciones web es creando un usuario que tiene acceso únicamente a hacer select o insert específicos o los que trabajan en modo paranóico dando acceso solo a los SP necesarios para que la aplicacion consulte o ingrese información.

Si tenes aplicaciones de escritorio no lo podes hacer así y usualmente sí creas usuarios en la DB con sus respectivos ACL a nivel de BD para que el usuario de escritorio no tenga acceso completo a la BD.
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: Juancho on August 02, 2012, 02:34:58 pm
para los proyectos que han echo  mx o juancho, si yo logro conectarme de una aplicación distinta a la que ellos hayan creado, hablemos de una aplicación destok o otro proyecto asp, puedo ver TOOODAS las tablas y Modificar TOOODO el contenido de las mismas, porque con mi usuario tengo acceso a TOOODO en la db..... o me equivoco?

jajajaj no tampoco Tekun, no te vayas al extremo... vaya por ejemplo en mi caso, en algunas aplicaciones lo que he hecho es denegar el acceso directo a las tablas, y todo pasa a travez de los SP. Unicamente doy acceso al SP, pero para la ejecucion del SP solicita una clave de acceso, la cual es guardada en una tabla de la BD de forma encriptada y es asociada al rol que puede ejectuar dicho SP.

Entonces asocio el SP/Rol, ahora bien, en la aplicacion web, en el Web.Config, almaceno la clave para ejecutar el SP (dependiendo del Rol), pero de forma encriptada, utilizando la encriptacion por maquina + una clave adicional, esto me permite que solo la maquina donde se esta ejecutando puede desencriptar la clave, aunqe se llevaran el Web.Config a otra maquina, o tuvieran acceso a el, necesitarian desencriptarlo en la maquina donde corre actualmente y la clave adicional que se esta utilizando.

Y a la hora de ejecutar el procedimiento desde la aplicacion web, dependiendo del rol, se pasa la contraseña a la BD para que pueda ejecutar el SP.

Ahora bien, en una de tantas quise utilizar los Roles de Aplicacion que vienen con MSSQL, pero tuve un problema con el EF, asi que por eso m toco inventar una manera con los SP. jajajaj xD

Luego tuve un intent con los SP certificados, pero de esto si no recuerdo que problema fue el que tuve... asi que mejor continue como lo he venido haciendo.. xD

La ventaja es que en cualquier RDBMS podria implementar esto en los procedimientos... quizas no sea la mejor forma, pero bueno.... xD

Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: tekun on August 02, 2012, 04:22:56 pm
.....
Lo que se termina haciendo con aplicaciones web es creando un usuario que tiene acceso únicamente a hacer select o insert específicos o los que trabajan en modo paranóico dando acceso solo a los SP necesarios para que la aplicacion consulte o ingrese información.

que paranoíco salio este ve

... vaya por ejemplo en mi caso, en algunas aplicaciones lo que he hecho es denegar el acceso directo a las tablas, y todo pasa a travez de los SP. Unicamente doy acceso al SP

XD



cuando di clic en publicar y revise el texto me puse a pensar en el acceso a la DB y si por problemas de accesos, es que se recurre a este tipo de alternativas


me imagine lo siguiente, que se conectan a la db con 1 único user y pwd.... y que quienes utilizan el sistema los validan nada más en tablas, no de roles en la DB...


MX lo aclaro con lo de los portales, es que la verdad yo nunca he utilizado a una empresa de hosting para una de mis app, siempre he tenido la "suerte" de poseer el control de todo... por eso es que juzgue de manera precipitada....
Title: Re:Ocultar Paginas segun tipo de usuarios
Post by: mxgxw on August 02, 2012, 05:11:57 pm
que paranoíco salio este ve

XD



cuando di clic en publicar y revise el texto me puse a pensar en el acceso a la DB y si por problemas de accesos, es que se recurre a este tipo de alternativas


me imagine lo siguiente, que se conectan a la db con 1 único user y pwd.... y que quienes utilizan el sistema los validan nada más en tablas, no de roles en la DB...


MX lo aclaro con lo de los portales, es que la verdad yo nunca he utilizado a una empresa de hosting para una de mis app, siempre he tenido la "suerte" de poseer el control de todo... por eso es que juzgue de manera precipitada....


La mayoría de las apps web lástimosamente funcionan así. Muchas veces porque es poco práctico (aka "Monteme este joomla para ahora en la noche" o "hagame esta app para la otra semana") estar revisando a detalle todos los accesos.

Por eso se toman algunas alternativas, por ejemplo: limitas los permisos del usuario de la db una vez se ha implementado la aplicación. Limitas las IP de donde te podes conectar al gestor, por ejemplo los gestores de los servicios de webhosting raramente vienen configurados para aceptar conexiones remotas, muchos incluso tienen bloqueados por firewall los puertos de acceso a los gestores de DB.

Además que muchas veces no es tan práctico, ponele un ejemplo: SVCommunity... ¿Harías tu 10,000 usuarios en tu gestor de base de datos pensando por la seguridad? Realmente eso es una vieja discusión... ¿Hasta donde llega lo que se puede hacer en el gestor DB y lo que se puede hacer en la Aplicación? Al final todo depende de que tan práctico y de que tan grande sea el beneficio adicional o las restricciones de seguridad que te obliguen a ponerte en modo "paranoico" jejejeje

Igual tenes que evaluar, lo de la autorización a nivel de SP puede sonar paranoico pero si tu aplicación requiere ese nivel de verificación y adicionalmente tenes que llevar un registro de todas las transacciones, pues algo similar te tocará implementar.

Los frameworks de diseño de aplicaciones si te fijas están diseñados mayormente "asumiendo" 1ro, que tu aplicacion se conecta mediante uno o varios usuarios del gestor de la DB y  2do que este usuario tiene acceso a las tablas o vistas que luego se utilizan en el ORM, prácticamente la mayoría de los frameworks, portales y CMS de aplicaciones web funcionan de esa manera.

Para aplicaciones de escritorio es harina de otro costal, obviamente ahí sí TENES que limitar los accesos a nivel de bases de datos, y ahí tiene muchísimo más sentido implementar autenticación usando el AD (porque se supone que tu DB tambien autentica usando el AD) y definiendo ACLs a objetos específicos. Ya que no podes controlar que medio se utiliza para conectarse a tu gestor de bases de datos, en un hosting pagado si podes limitar hasta cierto punto quien se conecta o no.