jueves, 12 de diciembre de 2013

Suplantar Usuarios en Sharepoint 2013 y verificar la pertenencia a Grupos

Os quiero explicar una de esas cosas tan simples que uno quiere saber, como por ejemplo a que grupos pertenece un usuario.

Resulta que no es nada fácil ni mas ni menos hay que recuperar al usuario, suplantarlo, desactivar la captura de excepciones de seguridad y entonces podemos mirar y actuar sin restricciones en nombre de otro usuario.... que miedo.

Os quiero resaltar 4 cosas complejas metidas en una sola función.

1º En Rosa: Como recuperar un usuario concreto (SPUser) de la web actual
2º En rojo : Como abrir un SPSite Suplantando a un usuario, con el truco del userToken y el ID de Site/Web, sin sus contraseña... no nos hace falta.
3º En verde : Como desactivar la captura de Excepciones de Acceso denegado
4º En Azul : Como verificar la pertenencia a un grupo del usuario suplantado.

Nota: Recordad que dentro de un RunWithElevated no podemos usar directamente el SPContext.Current.Site ni el SPContext.Current.Web, tan solo podemos recuperar el ID para crear el objeto dentro del codigo de privilegios elevados.

Espero que os resulte útil este "agujero de seguridad" de sharepoint.
Nadie os impide suplantar a gente.... ni ser malos.
Funciona en todas las versiones de Sharepoint 2007,2010,2013.

 public List<string> GetAllGroupsFromUser(string sLogin)
        {
            List<string> listapertenencia = new List<string>();

            userName = sLogin;
            SPUser usuario;
            try
            {
                usuario = SPContext.Current.Web.AllUsers[userName];
            }catch(Exception ex)
            {
                usuario = null;
            }

            if (usuario != null)
            {
                SPUserToken userToken = SPContext.Current.Web.AllUsers[userName].UserToken;
                SPSecurity.RunWithElevatedPrivileges(delegate()
                            {
                                bool AccessDeniedflag = SPSecurity.CatchAccessDeniedException;
                                SPSecurity.CatchAccessDeniedException = false;
                                try
                                {

                                    using (SPSite contextSiteColl = new SPSite(SPContext.Current.Site.ID, userToken))
                                    {

                                        using (SPWeb contextSite = contextSiteColl.OpenWeb(SPContext.Current.Web.ID))
                                        {
                                            foreach (SPGroup grp in contextSite.SiteGroups)
                                            {
                                                if (contextSite.SiteGroups[grp.Name].ContainsCurrentUser)
                                                {
                                                    listapertenencia.Add(grp.Name);
                                                }
                                            }
                                        }

                                    }
                                }
                                catch (UnauthorizedAccessException ex)
                                {
                                    listapertenencia.Add("---"); //Error
                                }
                                finally 
                                {
                                    SPSecurity.CatchAccessDeniedException = AccessDeniedflag;
                                }
                                  
                            });
            }
            return listapertenencia;
        }