none
Login en ASP.NET VB con SQL RRS feed

  • Pregunta

  • Hola colegas como saben soy novato en esto y para el proyecto que estoy haciendo en la empresa que trabajo me han planteado lo siguiente, si existe una forma de hacer login con acceso a varias bases de datos les pondré un ejemplo haber si me explico con claridad

    DB1

    DB2

    DB3

    DB4

    usuario1 

    usuario2

    usuario3

    cuando el usuario1 inicie sesión podrá ver todas las base de datos y manejarlas

    cuando el usuario2 inicie sesión podrá ver las db 1, 2 y 4

    cuando el usuario3 inicie sesión podrá ver las db 2 y 4

    espero me puedan apoyar saludos cordiales

    domingo, 23 de agosto de 2015 23:08

Todas las respuestas

  • hola

    cuando dices "podra ver" a que te refieres ? tendras acces al connection string a estas base de datos

    podrias crear una db adicional donde configurar la seguridad y login, en esta db definiras la tabla de usuario, ñla asociacion de estos a las distinas dbs, etc

    entonces el login lo realizarias con asp.net membership custom contra esta base de datos, despues el resto lo manejarias usando los connection string a las dbs que cada uno tenga acceso

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    domingo, 23 de agosto de 2015 23:17
  • hola leandro si algo parecido donde cuando entren los usuarios puedan accesar o ver solo las bd que se les asigne, pero la verdad no tengo ni la más mínima idea no se si tengas algún tutorial para poder guiarme 

    gracias

    lunes, 24 de agosto de 2015 0:56
  • >>si algo parecido donde cuando entren los usuarios puedan accesar o ver solo las bd que se les asigne

    pero que diseño de datos tienes ?

    vas a usar una db separa para definir la autenticacion? piesas usar asp.net membership para el login

    una cosa es el login y otra distinta es como aplicas la seguridad

    primero debes autenticar al usuario, ingresando usuario y password, despues de eso recuperas que dbs tinees acceso y solo le permites consultar a estas unicamente, pero son dos operaciones diferentes

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    lunes, 24 de agosto de 2015 3:10
  • pues lo que tengo pensado es en una base de datos separada tener las tablas del login con la siguiente estructura

    tabla_usuarios

    id

    usuario

    password

    tablamiembro

    id

    id_usuario ó nombre de usuario

    dbacceso

    pero no se si así está correcto de este modo es que ocupo las relaciones uno a varios ya que un usuario puede tener acceso a varias db

    tu que me aconsejas o como sería la forma correcta como te comente soy novato en esto y no se cual sea la forma correcta de hacerlo

    lunes, 24 de agosto de 2015 22:55
  • Esto lo quieres haces para una aplicación? por que si las bases de datos se encuentran en la misma instancia, tu puedes crear usuarios que tengan acceso a ellas, es decir puedes crear un usuario con acceso a todas o un usuario con acceso a alguna de ellas o incluso solo a parte de ellas.

    Pero este acceso es el acceso propio de la base de datos.

    How to grant a SQL Server login access to a database

    Granting Access to a SQL


    Ing. Carlos Monroy MCP, MCAD, MCSD, MCTS

    lunes, 24 de agosto de 2015 23:07
  • hola carlos lo estoy haciendo para una aplicación web para una empresa hotelera donde he creado un motor de reservaciones, el mismo se implementara para distintos hoteles y cada hotel lleva una base de datos pero la parte administrativa quieren que sea desde un sólo sitio web y según el hotel que se loguee tenga acceso a la base de datos que le corresponde
    lunes, 24 de agosto de 2015 23:13
  • Entonces el acceso lo vas a controlar desde tu aplicación, no tanto desde la base de datos, es decir cada hotel tendrá acceso a su propia información pero tu aplicación sera la que hará el direccionamiento.

    Podrías manejar varias connection string dentro del web config y tener este encriptado, o incluso podrias manejar una, y solo cambiar la ubicación de la base de datos, tu aplicación seria la que administraría los accesos.

    How to: Read Connection Strings from the Web.config File

    Si quiere usar una tabla como la que planteas la clase sqlconnectionstringbuilder te ayuda a generar la cadena de conexion

    SqlConnectionStringBuilder Class




    Ing. Carlos Monroy MCP, MCAD, MCSD, MCTS

    lunes, 24 de agosto de 2015 23:26
  • gracias carlos, tendrás algún ejemplo que me muestres porque la verdad no he entendido mucho de lo que he visto en los foros SqlConnectionStringBuilder Class
    martes, 25 de agosto de 2015 1:45
  • es una clase muy sencilla, que te ayuda a armar las cadenas de conexión,

    SqlConnection myConnection = new SqlConnection();
     
    SqlConnectionStringBuilder myBuilder = new SqlConnectionStringBuilder();
    myBuilder.UserID = "sa";
    myBuilder.Password = "admin@123";
    myBuilder.InitialCatalog = "test";
    myBuilder.ConnectTimeout = 30;
    myConnection.ConnectionString = myBuilder.ConnectionString;
    mira este ejemplo, creas un conectionstringbuilder y empiezas a dar cada uno de los parámetros de la cadena de conexión, parámetros que vivirán en tu base de datos, y con la propiedad conectionString obtienes la cadena que emplearas para entrar a la base de datos


    Ing. Carlos Monroy MCP, MCAD, MCSD, MCTS

    martes, 25 de agosto de 2015 1:56
  • mi duda es si esto tengo que hacerlo por cada una de las base de datos a las que se requiera el acceso y como le hago para que esto me lea la tabla de la base de datos que me validara a cuales db tiene o no acceso el usuario no se si me explico a parte ocupo vb no c#
    martes, 25 de agosto de 2015 2:07
  • Hola Maikel Cutiño Fernandez,

    ¿Estás iniciando el proyecto? Sólo si estas iniciando el proyecto la manera correcta es que tengas una tabla [Empresa] que defina una instancia distinta para cada cliente, lo que se conoce como multi-empresa que es una aproximación al concepto de tenencia múltiple (multi-tenancy)

    martes, 25 de agosto de 2015 2:27
  • si pero a lo que me refiero es que no tenga que seleccionar la empresa que quiero administrar desde el formulario de login eso lo hago ya en el main de la aplicación no se si me explico porque he visto que en algunos sistemas tienes que en el login decir cual empresa deseas administrar y entras a la base de datos eso así si se hacerlo pero en el caso que me solicitan no deben de verse las otras empresas a no ser que tengas acceso a dichas empresas y ya en el main de la aplicación con un DropDownList es que se selecciona a que empresa administrar y se cargan entonces los datos del string de esa empresa y en sí lo que no quiero es tener que estar modificando los script cada ves que se de de alta una nueva empresa

    martes, 25 de agosto de 2015 2:40
  • Hola Maikel Cutiño Fernandez,

    Si ya tienes definida las empresas y los usuarios entonces bastará con tener una tabla [usuarios_empresas] que defina la pertenencia.

    martes, 25 de agosto de 2015 3:05
  • si la tengo también de hecho mi procedimiento almacenado para el login es el siguiente

    ALTER Procedure [dbo].[validar_usuario]

    @usuario varchar(50),
    @password varchar(50)

    As
    Begin
    Select dbo.convenios.correo, dbo.usuarios.correo
    from dbo.usuarios, dbo.convenios 
    where dbo.usuarios.correo = @usuario AND dbo.usuarios.password = @password AND dbo.convenios.correo = @usuario AND dbo.usuarios.estatus = 'Activo'
    End

    y tengo dos tablas una con los usuarios y otra con las empresas a las que tienen permisos sólo me falta definir como enviarlos a las bases de datos esas ya que no manejo una sola base de  datos sino que manejo varias me explico???

    martes, 25 de agosto de 2015 3:12
  • Hola Maikel Cutiño Fernandez,

    Inicie mencionando que sólo te serviría mi propuesta en caso estés iniciando el proyecto, porque en realidad no necesitas tener "n" bases de datos sino  que una sola que opere con todas las instancias de clientes que tengas.

    Pero vamos, si ya estas sobre la marcha puedes crear la cadena de conexión de manera dinámica, imagino que lo único distinto es el nombre de la base de datos, ¿verdad?. Púes bien, deberás tener una convención para nombrar las bases de datos como por ejemplo [NombreProducto] + [CodigoEmpresa]. Una vez se haya autenticado el usuario, ya puedes saber a que empresa pertenece y por tanto puedes conocer el código  de la empresa y ello será suficiente información como para crear la cadena.

    Dim CadenaConexion As String = string.Format("Integrated Security=SSPI; Data Source=SERVIDOR\INSTANCIA; Initial Catalog={0};", NombreProducto + CodigoEmpresa)

    Si la solución propuesta atendió su consulta no olvide marcarla como respuesta.

    Willams Morales
    Arequipa - PERÚ

    martes, 25 de agosto de 2015 3:26
  • >>pero no se si así está correcto de este modo es que ocupo las relaciones uno a varios ya que un usuario puede tener acceso a varias db

    si es correcto es una relacion uno a muchos

    pero usas el id para relacionar las tablas no el nombre

    no entiendo porque le pones el nombre "tablamiembro" si solo define las dbs a la cual tendra acceso, aunque bueno no conozco del todo el dominio que modelas puede que sea correcto

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 25 de agosto de 2015 4:06
  • Carlos

    >>Podrías manejar varias connection string dentro del web config y tener este encriptado

    creo que deberias analizar la situacion que se plantea, de verdad vas a mantener la configuracion de muchos clientes en el web.config ? digo pueden tener 50, 100, mil hoteles cada uno con su db y deberias configurar cada uno en el web.config, lo ves viable ?

    no me parece muy mantenible


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 25 de agosto de 2015 4:09
  • hola

    >>he visto que en algunos sistemas tienes que en el login decir cual empresa deseas administrar y entras a la base de datos

    a ver, hay varias formas de modelar esto que planteas

    - una es crear una base de datos con al estructura por cada empresa que tengas, que imagino es el camino que estas evaluando

    - la otra es crear una unica base de datos para todas las empresas, entonces diferencias la informacion de cada hotel por un campo adicional en cada tabla indicando a cual pertenece ese registro, en este caso tendras una tabla de usuario y otra de hoteles, pero cuando crees, no se, digamos habitaciones, personal, clientes, facturas, todas las tablas llevaran un campo obligatorio que se relaciona con la tabla de hoteles

    ambos caminos son validos, cada uno tiene sus pro y contras, la administracion de una sola db es mucho mas simple, pero quizas sea un problema si el cliente es algo reasio al momento de persistir su informacion con otras empresas, digo si se entera que el y sus competidores registran en la misma db puede que no guste

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 25 de agosto de 2015 4:16
  • hola williams haber si te comprendí bien al 

    Dim CadenaConexion As String = string.Format("Integrated Security=SSPI; Data Source=SERVIDOR\INSTANCIA; Initial Catalog={0};", NombreProducto + CodigoEmpresa

    le asigno el resultado de la consulta que me carga el DropDownList  con los parametros que cumpla mi procedimiento almacenado, no se si así lo vez bien algo como

    //Cadena de Conexion Principal

    Dim CadenaConexion As String = string.Format("Integrated Security=SSPI; Data Source=SERVIDOR\INSTANCIA; Initial Catalog='"& Empresa &"';"

    //Donde defino la base de datos a ocupar

    Dim Empresa As String = DropDownList1.Text

    Protected Sub DropDownList1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles DropDownList1.SelectedIndexChanged

            If DropDownList1.SelectedValue = 1 Then
                Empresa = DropDownList1.SelectedValue = 1
            End If
            If DropDownList1.SelectedValue = 2 Then
                Empresa = DropDownList1.SelectedValue = 2
            End If

        End Sub

    o como crees esa es mi manera si es que funciona jejeje o si es que está bien ps la verdad soy novato en esto y en algunas cosillas paso trabajo

    saludos

    martes, 25 de agosto de 2015 4:17
  • Hola Maikel Cutiño Fernandez,

    A ver, las best-practices mencionan que una cadena de conexión debería estar en un archivo de configuración (Web.config/App.config), la aplicación debe referenciar al archivo de configuración y obtener la cadena de conexión según el nombre de la sección.

    Pero, para tu caso, lo que necesitamos es generar la cadena de conexión en tiempo de ejecución y para ello puedes hacer uso del ejemplo que te propuse o algo mejor, usar un generador de cadena de conexión que permita crear una cadena de conexión validando la sintaxis. Concatenar la cadena de conexión trae consigo vulnerabilidades en la seguridad y falta de legibilidad del código, descartemos su uso.

    ¿Tu proveedor de datos es SqlClient? Pues bien, usaremos la clase SqlConnectionStringBuilder para crear la cadena de conexión, incluso aquí hay buenas practicas a seguir y una de ellas es crear cadenas de conexión a partir de archivos de configuración. ¿Qué es esto? bueno, hemos visto que lo único que varia entre los distintos clientes que tienes es la base de datos, entonces todos los elementos que son constantes los podemos almacenar en un archivo de configuración y luego en tiempo de ejecución completamos la cadena. 

    ¿Listo para los ejemplos?

    Vamos a crear una cadena de conexión "parcial" en el archivo Web.config

    'Agregamos una cadena de conexión con los atributos que tienen los mismos valores para todos tus clientes
    <connectionStrings>
      <clear/>
      <add name="CadenaConexionParcial" 
        connectionString="Integrated Security=SSPI; Data Source=SERVIDOR\INSTANCIA;"
        providerName="System.Data.SqlClient" />
    </connectionStrings>

    Estamos definiendo una cadena de conexión donde indicamos el tipo de autenticaciony el servidor, pero no estamos indicando la base de datos, ¿por qué? porque la base de datos depende el usuario que ha ingresado a la aplicación y como te dije anteriormente, ello lo completaremos en tiempo de ejecución.

    Ahora vamos con la clase SqlConnectionStringBuilder. La clase SqlConnectionStringBuilder tiene una sobrecarga del constructor que permite proporcionar una cadena de conexión,  ya intuyes de que cadena de conexión nos referimos, ¿verdad?, pues si, de la cadena de conexión parcial que hemos definido en el archivo de configuración.

    'Obtenemos la cadena de conexión "parcial"
    Dim CadenaConexion As String = ConfigurationManager.ConnectionStrings("CadenaConexionParcial").ConnectionString
    
    'Declaramos e instanciamos la clase SqlConnectionStringBuilder pasandole como argumento al constructor la cadena de conexión parcial
    Dim CadenaConexionParcial As New SqlConnectionStringBuilder(CadenaConexion)
    
    'Agregamos los valores faltantes como la base de datos
    CadenaConexionEmpresa.DataSource = BDEmpresa

    Aquí lo que hacemos es pasar como argumento la cadena de conexión parcial y luego la completamos en tiempo de ejecución, en el ejemplo asignamos al atributo DataSource una variable (BDEmpresa) que será la que contenga el nombre de la base de datos de la empresa según el usuario logeado.

    Finalmente, si quieres obtener la cadena de conexión completa bastará con:

    Dim CadenaConexionCompleta As String =  CadenaConexionEmpresa.ConnectionString


    Espero que está breve explicación te ayude en tu cometido.

    Si la solución propuesta atendió su consulta no olvide marcarla como respuesta.


    Willams Morales
    Arequipa - PERÚ

    martes, 25 de agosto de 2015 5:05
  • una duda BDEmpresa con que debo sustituirla eso no se como implementarlo por eso la idea de utilizar un DropDownList para cambiar de base de datos
    martes, 25 de agosto de 2015 6:46
  • o debo declarar en una clase todas las empresas
    martes, 25 de agosto de 2015 6:49
  • Hola Maikel Cutiño Fernandez,

    BDEmpresa es una variable cualquiera (puede ser un objeto en memoria, una propiedad de una clase, etc) que contiene el nombre de la base de datos asignada al usuario autenticado, ahora, un usuario podría estar relacionado con una o varias bases de datos; una es el escenario común, varias bases de datos cuando por ejemplo se trata de un usuario administrador, en este caso imagino que al momento de logearse y detectar el nombre de usuario se permitirá seleccionar una empresa a la que se desee conectar (sólo se mostrarán las empresas con las que el usuario esté relacionado). El usuario logeado, la empresa y demás información podría ser almacenada en un objeto Session o en una clase (no te doy mayores detalles de esto porque ASP NET es un perfecto desconocido para mi, puse mis ojos de manera directa sobre ASP NET MVC y hay algunos conceptos que no me son familiares). El valor de Session o de una propiedad de la clase que contenga la base de datos de la empresa seleccionada es la que asignarás al atributo DataSource de la clase SqlConnectionStringBuilder.

    Si la solución propuesta atendió su consulta no olvide marcarla como respuesta.

    Willams Morales
    Arequipa - PERÚ
    martes, 25 de agosto de 2015 14:40
  • bueno William siguiendo tus comentarios así tengo la configuración actual en el load de la pagina main que es donde selecionaré la base de datos a la que me dirigiré

     Dim CadenaConexion As String = ConfigurationManager.ConnectionStrings("CadenaConexionParcial").ConnectionString
        Dim CadenaConexionParcial As New SqlConnectionStringBuilder(CadenaConexion)
        Dim empresas As String = cboEmpresas.Text
    (error 1)    CadenaConexionEmpresa.DataSource = empresas
        Dim CadenaConexionCompleta As String = (error 2)CadenaConexionEmpresa.ConnectionString

    sin embargo me da el siguiente error 

    Error 1 Se esperaba una declaración. D:\Web\neo\main.aspx.vb 10 5 neo

    Error 2 'CadenaConexionEmpresa' no está declarado. Puede que esté inaccesible debido a su nivel de protección. D:\Web\neo\main.aspx.vb 11 44 neo

    miércoles, 26 de agosto de 2015 22:03
  • Hola Maikel Cutiño Fernandez,

    ¿De dónde salio CadenaConexionEmpresa?

    Dim CadenaConexion As String = ConfigurationManager.ConnectionStrings("CadenaConexionParcial").ConnectionString
    
    Dim CadenaConexionParcial As New SqlConnectionStringBuilder(CadenaConexion)
    
    Dim empresas As String = cboEmpresas.Text
    
    CadenaConexionParcial.DataSource = empresas
    
    Dim CadenaConexionCompleta As String = CadenaConexionParcial.ConnectionString


    OFF TOPIC:

    Máximas en el desarrollo de software:

    Principio 1: DRY (Don't repeat yourself) No repitas código, encapsula y reutiliza.


    miércoles, 26 de agosto de 2015 22:13
  • del ejemplo anterior, me sigue marcando el error 1 de que se esperaba una declaración en

    CadenaConexionParcial.DataSource = empresas

    miércoles, 26 de agosto de 2015 22:28