How To: Utilizar PrincipalPermission para bloquear Funcionalidades
Introducción
Hace unos días hablando con Antiocol, comentábamos sobre como llevar a cabo el bloqueo de funcionalidades / pantallas / vistas ante la existencia de distintos usuarios propios de la aplicación, es decir, no son usuarios de Windows.
Me comento la existencia del atributo PrincipalPermission, y decidí investigar un poco acerca de este tema.
El problema
Dada una aplicación multiusuario, en el que encontramos los perfiles: Encargado, Dependiente y Mozo, tenemos una serie de controles de Usuario(WPF) o formularios(Winforms) que no van a ser accesibles por todos ellos.
Dentro de nuestra Base de Datos, no voy a entrar a su definición, tenemos una serie de usuarios y la asociación con los distintos perfiles, por ejemplo: Juan puede ser Encargado, dependiente y Mozo, y Pedro solo es mozo.
Tenemos dos controles:
- Facturación que va a ser solo accesible por el perfil Encargado.
- Almacén: que va a ser accesible por Encargado, Dependiente y Mozo
Para resolver, esta situación vamos a ver una posible solución con WPF, y PrincipalPermission.
Solución
Una posible aproximación para alcanzar el objetivo puede ser la siguiente:
En primer lugar, tendremos que establecer el usuario y los roles del mismo para asignárselos como Identidad a la hora de ejecutar la aplicación.
1: string NombreUsuario = ObtenerNombreUsuario();
2: GenericIdentity identidad = new GenericIdentity(NombreUsuario);
3: String[] roles = ObtenerRoles(NombreUsuario);
4: GenericPrincipal MyPrincipal =
5: new GenericPrincipal(identidad, roles);
6: Thread.CurrentPrincipal = MyPrincipal;
Una vez realizada la asignación de los permisos, va a llegar el momento de verificar si un control dado puede ser visualizado por la Identidad actual:
1: try
2: {
3:
4: PrincipalPermission MyPermission =
5: new PrincipalPermission(ObtenerUsuario(), "Mozo");
6: // Demand this permission.
7: MyPermission.Demand();
8: this.DataContext = new ViewModel.Control2();
9:
10: }
11: catch (SecurityException ex)
12: {
13:
14: this.Visibility = Visibility.Hidden;
15: }
El método Demand se del objeto PrincipalPermission es el encargado de comprobar si el usuario tiene el rol indicado. Si el usuario dispone de dicho rol podrá visualizar el control sin ningún problema, en caso contrario, se provocará una excepción del tipo SecurityException indicándolo.
Para el correcto funcionamiento de esta solución es necesario que se incluyan los siguientes using:
- System.Security.Principal
- System.Security.Permissions
- System.Threading
- System.Security
Espero que os sea de utilidad, y que comenteis otras formas que conozcais.
Un saludo