none
niveles de acceso en asp.net web RRS feed

  • Pregunta

  • hola, estoy construyendo un sistema web, estoy realizando modulo de inventario y facturacion etc.la pregunta como podria definir acceso a los asuarios dependiendo del nivel q tenga,...por ejemplo si el usuario administrador  q pueda navegar por ambos modulos, inventario y facturacion.

    usuario2 q solo pueda navegar en el modulo inventario nada mas...en el menu pueden estar desavilitado los modulo, y asi sucesivamente...

    nota:no hice uso del control de login q brinda visual-.. si no q cree una tabla en sql de usuario, niveles d acceso o modulos...no se si crear una clase para luego definir el acceso a los diferentes tipos de usuarios existentes...

    le agradesco a los miembros dell foro q me han ayudado con dudas, preguntas, informacion..

    saludos coordiales...


    yader leiva fonseca.. Nicaragua....

    miércoles, 14 de noviembre de 2012 1:46

Respuestas

  • Estimado yalefon-nic

    Como te comenta Leandro si estas armando tus "propias tablas" (por decirlo de alguna manera y no estas utilizando las que provee ASP.NET) Tendrias que crear un proveedore de roles personalizado o en el login obtener los roles u asignarlo al usuario logeado (sin tablas, sin proveedor)
    Seria bueno que nos comentes como estas "Logeando" al usuario, el codigo que utilizas asi te ayudamos mejor. Puedes?


    Acoto algo mas.
    ASP.NET Provee un sistema de membresia y roles, que estan soportados por Proveedores o sea componentes que obtienen estos datos desde las fuentes donde estan. Es decir si estan en un ActiveDirectory lo obtiene de ahi, si esta en una tabla SQL server lo obtiene de ahi. Ahora bien este ultimo proveedor de SQL Server esta basado a que implementes los objetos en la DB que genera ASP.NET (tablas, procedimientos almacenados). Hay una forma de registrarlos a estos objetos (es decir crearlos en la DB, hay un script que lo hace o mediante la herramienta aspnet_regsql.exe) y alli el proveedor por default de SQL debes pasarle la cadena de conexion y consulta a la DB por los usuarios (proveedores de membresia) o roles (proveedor de roles). Mas info te dejo unos enlaces mas abajo


    Sintesis:

    • Gracias a estos proveedores (el sistema que se basa en proveedores) podemos utilizar nuestros propias tablas 
      Y tendriams que crear un proveedor customizado/personalizado que sepa leer de esas tablas o del origen de datos que necesitemos
    • Utilizar los webcontrol de seguridad. Ayudan bastante en el desarrollo de webforms. Pero no es lo "esencial"
    • Podemos utilizar este sistema de Roles para autorizacion de paginas, carpetas, items en el menu, botones, incluso en el codigo (verificando que tiene la autorizacion correcta para ejecutarlo)

    Ahora bien.... 
    Estos proveedores funcionen muy bien con los webcontrol de seguridad de ASP.NET (Login, createUser, etc) o sino tendrias que escribir el codigo por ti mismo. Lo que ya hiciste tal cual comentas

    Entonces las dos opciones que tienes (que se me ocurren, si alguien tiene otras nos comente asi vamos expandiendo nuetro conocimiento)

    OPCION 1: Implementar un proveedor de Roles/Membresia personalizado
    Particulamente un trabajo de codigo. Pero que te queda ya armado para ser uytilizando en otros proyectos con las mismas tablas
    DEjo mas abajo enlaces para armar proveedores personalizados

    OPCION 2: Agregar "roles/funciones" sin necesidad de un proveedor (sobrescribiendo el usuario)
    Aqui la idea es que desde la clase FormsAuthenticationTicket puedes pasarle "datos de usuario" (propiedad UserData) que puede ser en este caso particular un cadena de roles. 
    Pero para asignar estos roles, no es automático en este caso, entonces hay que hacerlo en el evento Application_OnAuthenticateRequest de Global.assax poder obtener estos roles que guardamos en el ticket de usaurio (en la propiedad userdata) y sobrescribir al Usuario logeado mediante formulario con los roles asignados. Generamos un nueva identidad de usaurio con la clase GenericPrincipal

    La idea esta implementada aquí:


    En ambos casos podras utilizar los

    1. Webcontroles de Seguridad (y preguntar por el Rol) por ejemplo en el LoginView (presentar temples por roles)
    2. Podras utilizar desde codigo: IsUserInRole, 
    3. Podras decorar metodos con:   [PrincipalPermissionAttribute(SecurityAction.Demand, Role = "MyRole")]
    4. Podras utilizar en tus archivos de configuracion (web.config). Los tags de Autorizar/Denegar (allow/deny) usuarios y roles
      NOTA: Acuerdate que tienes el tag location para definir partes del contenido (paginas, carpetas) con una configuracion especial (para no estar colocando web.config en carpetas)
    <authorization>
      <allow users="fernandezja" roles="jedis,padowan" />
    	 ....
    </authorization>

    Enlaces que te pueden ayudar

    Espero que te sirva de ayuda o guia.


    Jose. A Fernandez | blog: http://geeks.ms/blogs/fernandezja

    miércoles, 14 de noviembre de 2012 14:44
  • por q no quiero usar los controles q proporciona visual si no crear querys y asi asignarle acceso a los diferentes modulos segun el nivel de acceso

    ok los controles y los proveedores no los uses, pero ojo la seguridad de acceso si debes usarla

    Login – Usando Password con Hash

    esta es fundamental para que el sitio sea seguro


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    jueves, 15 de noviembre de 2012 3:19
  • por lo de la encriptacion no afecta

    lo que si debes implementar es la seguridad de asp.net, definiendo el login en el config

    despues como verificas si esta correcto el usuario es indistinto pero usar esto

    Response.Redirect("Menu.aspx");

    no esta nada bien, debes hacer que asp.net redireccione y cree el ticket de autenticacion, como lo explico en el articulo usando

    FormsAuthentication.RedirectFromLoginPage(...

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    jueves, 15 de noviembre de 2012 15:43

Todas las respuestas

  • si estas creando la propia tabla entonces deberias tambien crear queries que permitan recuperar el rool del usuario y aplciar logica en la paginas para permitir o no realizar determianda accion

    pero es algo puntual que programas, salvo que quieras realziar alguna implementacion custom del RolProvider de asp.net

    sino es el caso entonces crea la query que recupera el o los roles de la persona y realiza los if en las pagians para ocultar opciones que no pueda realziar el usuario

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    miércoles, 14 de noviembre de 2012 1:55
  • Estimado yalefon-nic

    Como te comenta Leandro si estas armando tus "propias tablas" (por decirlo de alguna manera y no estas utilizando las que provee ASP.NET) Tendrias que crear un proveedore de roles personalizado o en el login obtener los roles u asignarlo al usuario logeado (sin tablas, sin proveedor)
    Seria bueno que nos comentes como estas "Logeando" al usuario, el codigo que utilizas asi te ayudamos mejor. Puedes?


    Acoto algo mas.
    ASP.NET Provee un sistema de membresia y roles, que estan soportados por Proveedores o sea componentes que obtienen estos datos desde las fuentes donde estan. Es decir si estan en un ActiveDirectory lo obtiene de ahi, si esta en una tabla SQL server lo obtiene de ahi. Ahora bien este ultimo proveedor de SQL Server esta basado a que implementes los objetos en la DB que genera ASP.NET (tablas, procedimientos almacenados). Hay una forma de registrarlos a estos objetos (es decir crearlos en la DB, hay un script que lo hace o mediante la herramienta aspnet_regsql.exe) y alli el proveedor por default de SQL debes pasarle la cadena de conexion y consulta a la DB por los usuarios (proveedores de membresia) o roles (proveedor de roles). Mas info te dejo unos enlaces mas abajo


    Sintesis:

    • Gracias a estos proveedores (el sistema que se basa en proveedores) podemos utilizar nuestros propias tablas 
      Y tendriams que crear un proveedor customizado/personalizado que sepa leer de esas tablas o del origen de datos que necesitemos
    • Utilizar los webcontrol de seguridad. Ayudan bastante en el desarrollo de webforms. Pero no es lo "esencial"
    • Podemos utilizar este sistema de Roles para autorizacion de paginas, carpetas, items en el menu, botones, incluso en el codigo (verificando que tiene la autorizacion correcta para ejecutarlo)

    Ahora bien.... 
    Estos proveedores funcionen muy bien con los webcontrol de seguridad de ASP.NET (Login, createUser, etc) o sino tendrias que escribir el codigo por ti mismo. Lo que ya hiciste tal cual comentas

    Entonces las dos opciones que tienes (que se me ocurren, si alguien tiene otras nos comente asi vamos expandiendo nuetro conocimiento)

    OPCION 1: Implementar un proveedor de Roles/Membresia personalizado
    Particulamente un trabajo de codigo. Pero que te queda ya armado para ser uytilizando en otros proyectos con las mismas tablas
    DEjo mas abajo enlaces para armar proveedores personalizados

    OPCION 2: Agregar "roles/funciones" sin necesidad de un proveedor (sobrescribiendo el usuario)
    Aqui la idea es que desde la clase FormsAuthenticationTicket puedes pasarle "datos de usuario" (propiedad UserData) que puede ser en este caso particular un cadena de roles. 
    Pero para asignar estos roles, no es automático en este caso, entonces hay que hacerlo en el evento Application_OnAuthenticateRequest de Global.assax poder obtener estos roles que guardamos en el ticket de usaurio (en la propiedad userdata) y sobrescribir al Usuario logeado mediante formulario con los roles asignados. Generamos un nueva identidad de usaurio con la clase GenericPrincipal

    La idea esta implementada aquí:


    En ambos casos podras utilizar los

    1. Webcontroles de Seguridad (y preguntar por el Rol) por ejemplo en el LoginView (presentar temples por roles)
    2. Podras utilizar desde codigo: IsUserInRole, 
    3. Podras decorar metodos con:   [PrincipalPermissionAttribute(SecurityAction.Demand, Role = "MyRole")]
    4. Podras utilizar en tus archivos de configuracion (web.config). Los tags de Autorizar/Denegar (allow/deny) usuarios y roles
      NOTA: Acuerdate que tienes el tag location para definir partes del contenido (paginas, carpetas) con una configuracion especial (para no estar colocando web.config en carpetas)
    <authorization>
      <allow users="fernandezja" roles="jedis,padowan" />
    	 ....
    </authorization>

    Enlaces que te pueden ayudar

    Espero que te sirva de ayuda o guia.


    Jose. A Fernandez | blog: http://geeks.ms/blogs/fernandezja

    miércoles, 14 de noviembre de 2012 14:44
  • hola  leandro y jose, gracias por el aporte, la verdad cree en sql 2005 las siguientes tablas. voy a poner la descripcion de cada una de ellas para ver si me dan una idea mas congreta, por q no quiero usar los controles q proporciona visual si no crear querys y asi asignarle acceso a los diferentes modulos segun el nivel de acceso...les agradesco su colaboracion...

    1.usuarios: contiene los siguientes campos, sele asigna una clave, el tipo de usuario y modulo donde va navegar..

    id_usuario.

    nombre_usuario

    Clave

    correo

    id_nivel

    id_modulo

    2.niveles:....para definir el tipo de acceso del usuario, ya sea administrador, operado etc.

    id_nivel

    descripcion

    3.modulos.....para definir los tipos de modulos existente del sistema, ejemplo inventario,facturacion, liquidacion etc..

    id_modulos

    descripcion

    saludos...




    yader leiva fonseca.. Nicaragua....

    jueves, 15 de noviembre de 2012 2:32
  • por q no quiero usar los controles q proporciona visual si no crear querys y asi asignarle acceso a los diferentes modulos segun el nivel de acceso

    ok los controles y los proveedores no los uses, pero ojo la seguridad de acceso si debes usarla

    Login – Usando Password con Hash

    esta es fundamental para que el sitio sea seguro


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    jueves, 15 de noviembre de 2012 3:19
  • hola leandro gracias siempre por lo aportes...se me habia olvidado decirles q tengo una funcion en sql q encripta las claves...entonces tengo dos opciones me inmagino, comensar de nuevo y hacer uso de passwoord con hash o seguir con lo q tengo....q es mas recomendable y seguro?

    dejo la funcion de sql...q encripta y desencripta..

    encripta..

         

    ALTER FUNCTION [dbo].[fnColocaClave] 
    (
        @Clave VARCHAR(25)
    )
    RETURNS VarBinary(255)
    AS
    BEGIN


        DECLARE @pass AS VarBinary(255)

        SET @pass = ENCRYPTBYPASSPHRASE('factsql',@Clave)       
      RETURN @pass
    END

       

    desencripta...

                    

    ALTER FUNCTION [dbo].[fnLeeClave] 
    (
        @Clave VARBINARY(8000)
    )
    RETURNS VARCHAR(25)
    AS
    BEGIN


        DECLARE @pass AS VARCHAR(25)

        SET @pass = DECRYPTBYPASSPHRASE('factsql',@Clave)

        RETURN @pass

    END

    entonces para guardar mis login desde la aplicacion tengo algo como esto...agregar nuevos login..

                                                  

      protected void Button1_Click1(object sender, EventArgs e)
            {//boton agregar


                    //se declaran las variables

                    SqlConnection cnx;
                    SqlCommand query;
                    Object res;

                    cnx = new SqlConnection(cx);
                    cnx.Open();
                    try
                    {
                        query = new SqlCommand();
                        query.CommandType = CommandType.Text;
                        query.CommandText = "Insert into Usuario(NombreUsuario,Password,Id_niveles,Correo,Id_modulos)values(@NombreUsuario,dbo.fnColocaClave(@Password),@Id_niveles,@Correo,@Id_modulos)";

                        query.Parameters.AddWithValue("@NombreUsuario", TextBox2.Text);
                        query.Parameters.AddWithValue("@Password", TextBox3.Text);
                        query.Parameters.AddWithValue("@Id_niveles", DropDownList1.SelectedValue);
                        query.Parameters.AddWithValue("@Correo", TextBox4.Text);
                        query.Parameters.AddWithValue("@Id_modulos", DropDownList2.SelectedValue);
                        query.Connection = cnx;

                        res = new Object();
                        res = query.ExecuteScalar();
                        //   GridView1.DataSource = query;
                        GridView1.DataBind();

                        ////limpiar los controladores


                        TextBox2.Text = "";
                        TextBox3.Text = "";
                        TextBox4.Text = "";        

                        if (!(res is DBNull))
                        {
                            Response.Write("<script language=javascript>");
                            Response.Write("alert('datos guardados correctamente')");

                            TextBox2.Focus();

                            Response.Write("</script>");


                        }
                    }
                catch(SqlException){}
                finally{

                    if (cnx.State == ConnectionState.Open) cnx.Close();
                    if (cnx.State == ConnectionState.Broken) cnx.Close();

                    }
                    //se actualiza el grid
                    gridview();


            }   

    para conectarme al sistema una ves creado el login tengo algo como esto..  

     protected void Button1_Click1(object sender, EventArgs e)
            {

                int IdUser = 0;

                string msg = "Usuario no Existe, Debe de crear su cuenta para accesar al sistema....!";


                SqlConnection cnx = new SqlConnection(cx);

                SqlCommand cmd = new SqlCommand("SELECT IdUser FROM Usuario WHERE NombreUsuario=@NombreUsuario and dbo.fnLeeClave(Password) = @Password", cnx);
                try
                {
                    cmd.CommandType = CommandType.Text;

                    cmd.Parameters.AddWithValue("NombreUsuario", TextBox1.Text.Trim());
                    cmd.Parameters.AddWithValue("Password", TextBox2.Text.Trim());

                    cnx.Open();

                    IdUser = Convert.ToInt32(cmd.ExecuteScalar());
                    cmd.Parameters.Clear();
                    cmd.Dispose();


                    if (IdUser > 0)
                    {
                        msg = "Usuario Conectado al Sistema.....!";

                        Response.Redirect("Menu.aspx");

                        //this.TextBox1.Text = "";
                        //this.TextBox1.Focus();

                    }

                }

                catch (SqlException )
                {

                }
                finally
                {
                    if (cnx.State == ConnectionState.Open)
                    {
                        cnx.Close();
                        cnx.Dispose();
                    }
                }

                Label4.Text = msg;
                this.TextBox1.Text = "";
                this.TextBox1.Focus();


            }      saludos

    espero q esten mas claro de lo q estoy haciendo y tratando de hacer, con ayuda experta mi sistema quedaria con una mejor base. ...

                                                                  

    yader leiva fonseca.. Nicaragua....

    jueves, 15 de noviembre de 2012 14:37
  • por lo de la encriptacion no afecta

    lo que si debes implementar es la seguridad de asp.net, definiendo el login en el config

    despues como verificas si esta correcto el usuario es indistinto pero usar esto

    Response.Redirect("Menu.aspx");

    no esta nada bien, debes hacer que asp.net redireccione y cree el ticket de autenticacion, como lo explico en el articulo usando

    FormsAuthentication.RedirectFromLoginPage(...

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    jueves, 15 de noviembre de 2012 15:43
  • hola, si entendi entonces tendria hace uso de password hash..o podria trabajarlo con lo q tengo..

    saludos...


    yader leiva fonseca.. Nicaragua....

    jueves, 15 de noviembre de 2012 16:52