Pregunta

Necesito saber cómo implementar la seguridad general para una aplicación C #. ¿Qué opciones tengo al respecto? Preferiría usar un marco existente si satisface mis necesidades. No quiero reinventar la rueda.

Mis requisitos son los siguientes:

  • la autenticación habitual de nombre de usuario / contraseña
  • gestión de usuarios: asignar permisos a los usuarios
  • gestión de roles: asigne usuarios a roles, asigne permisos a roles
  • autorización de usuarios basada en su nombre de usuario y función

Estoy buscando un marco / biblioteca gratuito / de código abierto que haya sido probado y utilizado por la comunidad .Net.

Mi aplicación adopta un enfoque cliente / servidor, con el servidor ejecutándose como un servicio de Windows, conectándose a una base de datos de SQL Server. La comunicación entre el cliente y el servidor se realizará a través de WCF.

Otra cosa importante es que necesito poder asignar permisos específicos de usuarios o roles para Ver / Actualizar / Eliminar una entidad específica, ya sea un Cliente, o un Producto, etc. Por ejemplo Jack puede ver un determinado número de 3 de cada 10 clientes, pero solo actualiza los detalles de los clientes de Microsoft, Yahoo y Google, y solo puede eliminar Yahoo.

¿Fue útil?

Solución

Para seguridad de grano grueso, puede encontrar útil el código principal incorporado; el objeto de usuario (y sus roles) están controlados en .NET por el "principal", pero útilmente el tiempo de ejecución en sí mismo puede hacer cumplir esto.

La implementación de un principal puede ser definida por la implementación, y generalmente puede inyectarse la suya; por ejemplo en WCF .

Para ver el tiempo de ejecución que impone el acceso aproximado (es decir, a qué funcionalidad se puede acceder, pero no se limita a qué datos específicos):

static class Roles {
    public const string Administrator = "ADMIN";
}
static class Program {
    static void Main() {
        Thread.CurrentPrincipal = new GenericPrincipal(
            new GenericIdentity("Fred"), new string[] { Roles.Administrator });
        DeleteDatabase(); // fine
        Thread.CurrentPrincipal = new GenericPrincipal(
            new GenericIdentity("Barney"), new string[] { });
        DeleteDatabase(); // boom
    }

    [PrincipalPermission(SecurityAction.Demand, Role = Roles.Administrator)]
    public static void DeleteDatabase()
    {
        Console.WriteLine(
            Thread.CurrentPrincipal.Identity.Name + " has deleted the database...");
    }
}

Sin embargo, esto no ayuda con el acceso detallado (es decir, "Fred puede acceder al cliente A pero no al cliente B").


Adicional; Por supuesto, para los detalles, simplemente puede verificar los roles requeridos en tiempo de ejecución, marcando IsInRole en el principal:

static void EnforceRole(string role)
{
    if (string.IsNullOrEmpty(role)) { return; } // assume anon OK
    IPrincipal principal = Thread.CurrentPrincipal;
    if (principal == null || !principal.IsInRole(role))
    {
        throw new SecurityException("Access denied to role: " + role);
    }
}
public static User GetUser(string id)
{
    User user = Repository.GetUser(id);
    EnforceRole(user.AccessRole);
    return user;
}

También puede escribir sus propios objetos principales / de identidad que realizan pruebas / almacenamiento en caché de los roles, en lugar de tener que conocerlos por adelantado:

class CustomPrincipal : IPrincipal, IIdentity
{
    private string cn;
    public CustomPrincipal(string cn)
    {
        if (string.IsNullOrEmpty(cn)) throw new ArgumentNullException("cn");
        this.cn = cn;
    }
    // perhaps not ideal, but serves as an example
    readonly Dictionary<string, bool> roleCache =
        new Dictionary<string, bool>();
    public override string ToString() { return cn; }
    bool IIdentity.IsAuthenticated { get { return true; } }
    string IIdentity.AuthenticationType { get { return "iris scan"; } }
    string IIdentity.Name { get { return cn; } }
    IIdentity IPrincipal.Identity { get { return this; } }

    bool IPrincipal.IsInRole(string role)
    {
        if (string.IsNullOrEmpty(role)) return true; // assume anon OK
        lock (roleCache)
        {
            bool value;
            if (!roleCache.TryGetValue(role, out value)) {
                value = RoleHasAccess(cn, role);
                roleCache.Add(role, value);
            }
            return value;
        }
    }
    private static bool RoleHasAccess(string cn, string role)
    {
        //TODO: talk to your own security store
    }
}

Otros consejos

Busque Proveedores de membresía de ASP.NET . No creo que el SQLMembershipProvider listo para usar funcione en su caso, pero es lo suficientemente fácil como para rodar su propio proveedor.

mi respuesta probablemente depende de la respuesta a esta pregunta: ¿Es esta una aplicación Enterprise que vive dentro de una red con Active Directory?

SI la respuesta es sí, entonces estos son los pasos que proporcionaría:

1) Crear grupos globales para su aplicación, en mi caso, tenía un grupo APLICADOR y un grupo APPADMIN.

2) Haga que se pueda acceder a su SQL Server en modo de AUTENTICACIÓN MIXTA, y luego asigne su (s) grupo (s) de APLICADOR como el INICIO DE SESIÓN DEL SERVIDOR SQL a su base de datos con los derechos CRUD apropiados para sus DB, y asegúrese de que accede al SERVIDOR SQL con Trusted Connection = True en su cadena de conexión.

En este punto, su tienda AD será responsable de la autenticación. Como está accediendo a la aplicación a través de una CONEXIÓN CONFIABLE, pasará la identidad de cualquier cuenta que ejecute la aplicación al Servidor SQL.

Ahora, para la AUTORIZACIÓN (es decir, decirle a su aplicación lo que el usuario conectado puede hacer) es una simple cuestión de consultar a AD para obtener una lista de grupos de los que el usuario conectado es miembro. Luego, verifique los nombres de grupo apropiados y cree su interfaz de usuario basada en la membresía de esta manera.

Así funcionan mis aplicaciones:

  1. Al iniciar la aplicación, las credenciales se basan en el usuario conectado, este es el aspecto principal de la autenticación (es decir, pueden iniciar sesión, por lo tanto, existen)
  2. Obtengo todos los grupos para la identidad de Windows en cuestión
  3. Compruebo el grupo de USUARIO estándar: si este grupo no existe para la identidad de Windows en cuestión, entonces es una FALLA de autenticación
  4. Verifico el grupo de usuarios ADMIN - Con esto existente en los grupos de usuarios, modifico la IU para permitir el acceso a los componentes de administración
  5. Mostrar la interfaz de usuario

Entonces tengo un objeto PRINCIPIO con los derechos / etc determinados, o utilizo variables GLOBALES a las que puedo acceder para determinar la interfaz de usuario adecuada al crear mis formularios (es decir, si mi usuario no es miembro del grupo ADMIN , luego ocultaría todos los botones ELIMINAR).

¿Por qué sugiero esto?

Es una cuestión de despliegue.

Según mi experiencia, la mayoría de las aplicaciones empresariales son implementadas por ingenieros de red en lugar de programadores; por lo tanto, tener autenticación / autorización para ser responsabilidad de AD tiene sentido, ya que ahí es donde van los chicos de la red cuando se habla de autenticación / Autorización.

Además, durante la creación de nuevos usuarios para la red, un ingeniero de redes (o el responsable de crear nuevos usuarios de la red) es más apto para recordar realizar tareas grupales mientras están en AD que el hecho de que tienen que hacerlo ingrese a una docena de aplicaciones para analizar las asignaciones de autorización.

Hacer esto ayuda con el laberinto de permisos y derechos que los nuevos empleados deben otorgarse o aquellos que dejan la empresa deben denegarse y mantiene la autenticación y la autorización en el repositorio central donde pertenece (es decir, en AD @ el controlador de dominio nivel).

Creo que está viendo algunos problemas distintos aquí: no es casualidad que la mayoría de los sistemas de seguridad separen la autenticación y la autorización.

Para la autenticación, la pregunta más importante es logística. O, ¿existe un lugar lógico para que estos usuarios vivan, ya sea localmente en la aplicación, en Active Directory, en alguna otra tienda LDAP o incluso en alguna otra aplicación? Exactamente dónde es bastante irrelevante: solo debemos ser capaces de identificar sólidamente a los usuarios y preferiblemente hacer de esa tarea el problema de otra persona. Al final del día, realmente solo necesita un identificador único y la comodidad de que Bob de contabilidad es en realidad Bob de contabilidad.

La autorización es la parte más interesante del problema aquí. Creo que, si es realmente preciso, realmente desea administrar esto completamente dentro de su aplicación, sin importar de dónde vengan los usuarios. Marc Gravell realmente encontró una buena manera de modelar al menos algo de esto: usar una implementación personalizada de IPrincipal y PrincipalPermission para administrar las cosas es una forma muy limpia de comenzar. Más allá de eso, puede utilizar técnicas como este para tomar decisiones de autorización más complejas de una manera bastante limpia.

Usaría el término - 'RBAC' (sistema de control de acceso basado en roles) como la solución a todos sus requisitos.

No entraría en muchos detalles para explicar 'RBAC' aquí, sino que lo describiría brevemente como:

Básicamente contiene 3 características.

1) Autenticación: confirma la identidad del usuario. Por lo general, se realiza a través de cuentas de usuario y contraseñas o credenciales.

2) Autorización: define lo que el usuario puede hacer y lo que no puede hacer en una aplicación. Ex. Se permite "modificar el pedido", pero no se permite "crear un nuevo pedido".

3) Auditoría de acciones del usuario en aplicaciones. - Realiza un seguimiento de las acciones de los usuarios en las aplicaciones, así como de quién ha otorgado qué acceso a qué usuarios.

puedes consultar RBAC en wiki aquí.

https://en.wikipedia.org/wiki/Role-based_access_control

Ahora, con respecto a la respuesta a sus requisitos, una de las posibles soluciones es extender la membresía de ASP.NET según sus necesidades.

Y con respecto a algunos marcos listos para usar, recomendaría VisualGuard para lo que trabajo, debe verificar esto, hace todo lo que necesita muy fácilmente, y lo más importante es, administra todos sus usuarios, roles, permisos y aplicaciones a través de la Consola de administración central, y para definir permisos , los administradores no requieren el conocimiento del desarrollador, es decir, él / ella puede crear restricciones en las actividades a través de la interfaz de usuario.

también puede consultar este artículo para comprender mejor los permisos y el sistema basado en roles.

http://www.visual-guard.com/EN/net-powerbuilder-application-security-authentication-permission-access-control-rbac -artículos / dotnet-security-article-ressources / role-based-access-control-source_soforum.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top