sábado, 25 de febrero de 2012

Privilegios elevados en código de Sharepoint

SharePoint utiliza impersonation  de ASP.Net para personalizar la plataforma basado en  el usuario actual autorizado. Objetos de SharePoint son conscientes de la identidad del usuario y muchas partes de SharePoint sacan provecho de esta capacidad. Por ejemplo, cuando llegue a las listas en un sitio a través de la API, que sólo ven los que el usuario actual tiene acceso.

Si utiliza la autenticación de Windows y el código llama el modelo de objetos de SharePoint a partir de un proceso de trabajo de IIS, la solicitud debe suplantar la identidad del usuario que realiza la llamada. Sharepoint Foundation configura ASP.NET para suplantar al usuario que llama de forma automática, pero su código puede funcionar inesperadamente, o no, si se suspende la suplantación.  Más info: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsite.aspx

Cuando usar RunWithElevatedPrivileges y cuando no

RunWithElevatedPrivileges is a great way to solve the database connection problem, but often it can become somewhat of a Pandora’s box. It can become a go-to tool for every permission error encountered in SharePoint code. However, there are some issues that can occur with overuse of this style of programming, not least of which is that you lose some core SharePoint functionality inherent with impersonating the user.

A StackOverflow discussion about the pitfalls of RunWithElevatedPrivilges is a good summary and starting point for reading on the subject. Also, I’ve included below 3 good references for further reading on the topic.

A veces para suspender la impersonalización de usuario, es posible usar “SPSecurity.RunWithElevatedPrivileges”.

RunWithElevatedPrivileges es una gran manera de resolver el problema de conexión de base de datos, pero a menudo puede llegar a ser algo así como una caja de Pandora.Puede convertirse en una herramienta de go-to para cada error de permiso encontrado en el código de SharePoint.Sin embargo, hay algunos problemas que pueden ocurrir con el uso excesivo de este estilo de programación, no menos importante de los cuales es que se pierde la funcionalidad de SharePoint básico inherente a suplantar al usuario.

Mejores prácticas en el uso de RunWithElevatedPrivileges

  • Evite usar SPSecurity.RunwithElevatedPrivilege para acceder al modelo de objetos de Sharepoint. Use SPUserToken para impersonalización con SPSite.
  • Si usas SPSecurity.RunwithElevatedPrivilege, has un dispose de todos los objectos en el delegate. No pases objectos de SharePoint fuera del método RunwithElevatedPrivilege.
  • Sólo use SPSecurity.RunwithElevatedPrivilege para hacer llamadas externas bajo la identidad del app pool. No lo uses para elevar los privilegios de objectos de Sharepoint.
  • Siempre usa el constructor SPSite con una instancia de SPUserToken para crear un contexto de seguridad con privilegios elevados. Para impersonalizar el sistema, usa la propiedad SystemAccount.UserToken del actual contexto SPSite, ej:
    var site = new SPSite(SPContext.Current.Site.ID,  SPContext.Current.Site.SystemAccount.UserToken);
  • Evitar pasar objetos de Sharepoint entre diferentes contextos de seguridad (SPSiteinstances), con exception de SPUserToken. Un objeto SPUSer creado en un SPSite A no puede pasarse a un SPSite B. Esto puede ser fuente de oscuros bugs.
  • Restring que assemblis pueden usa privilegios elevados corriendo en minimal trust, evita el uso de la GAC, y has auditoria de cualquier CAS policies deployada.

Algunos código útiles:

   1:  SPUserToken sysToken = SPContext.Current.Site.SystemAccount.UserToken;

   2:   

   3:  using(var systemSite = new SPSite(SPContext.Current.Site.ID, sysToken))

   4:  {

   5:      using (var sysWeb = systemSite.OpenWeb(SPContext.Current.Web.ID))

   6:      {

   7:          // Perform elevated actions here

   8:      }

   9:  }



---------------------------

 

   1:  private static void impersonateTest()
   2:  {
   3:     string siteStr = "http://mysharepointsite/";
   4:     SPSite tempSite = new SPSite(siteStr);
   5:     SPUserToken systoken = tempSite.SystemAccount.UserToken;
   6:     using (SPSite site = new SPSite(siteStr, systoken))
   7:     {
   8:         using (SPWeb web = site.OpenWeb())
   9:         {
  10:             //right now, logged in as Site System Account
  11:             Console.WriteLine("Currently logged in as: " +
  12:                                web.CurrentUser.ToString());
  13:             switchUser(web, siteStr, "BlackNinjaSoftware/MatthewCarriere");
  14:             switchUser(web, siteStr, "BlackNinjaSoftware/ShereenQumsieh");
  15:             switchUser(web, siteStr, "BlackNinjaSoftware/DonabelSantos");
  16:         }
  17:     }
  18:  }
  19:   
  20:  private static void switchUser(SPWeb web, string siteStr, string user)
  21:  {
  22:     //impersonate somebody else
  23:     SPUserToken userToken = web.AllUsers[user].UserToken;
  24:     SPSite s = new SPSite(siteStr, userToken);
  25:     SPWeb w = s.OpenWeb();
  26:     Console.WriteLine("Currently logged in as: " +
  27:                       w.CurrentUser.ToString() +
  28:                       "(" + w.CurrentUser.Name + ")"
  29:                      );
  30:  }



---------------------------

   1:  protected static SPUserToken GetSystemToken(SPSite spSite)
   2:  {
   3:      SPUserToken res = null;
   4:      bool oldCatchAccessDeniedException = spSite.CatchAccessDeniedException;
   5:      try
   6:      {
   7:          spSite.CatchAccessDeniedException = false;
   8:          res = spSite.SystemAccount.UserToken;
   9:      }
  10:      catch (UnauthorizedAccessException)
  11:      {
  12:          SPSecurity.RunWithElevatedPrivileges(delegate()
  13:          {
  14:              using (SPSite elevatedSPSite = new SPSite(spSite.ID))
  15:                  res = elevatedSPSite.SystemAccount.UserToken;      // (***)
  16:          });
  17:      }
  18:      finally
  19:      {
  20:          spSite.CatchAccessDeniedException = oldCatchAccessDeniedException;
  21:      }
  22:      return res;
  23:  }




 


Fuente:

http://tomresing.com/blog/Lists/Posts/Post.aspx?ID=53

http://daniellarson.wordpress.com/2008/06/06/best-practices-for-elevated-privilege-in-sharepoint/


http://dotnetfollower.com/wordpress/2011/03/sharepoint-how-to-get-systemaccount-token/


Más información:


http://www.arboundy.com/2011/02/sharepoint-run-with-elevated-permissions-vs-impersonate/

No hay comentarios:

Publicar un comentario