Não é possível permitir que visitantes adicionem webpart de usuário apenas em algumas páginas

sharepoint.stackexchange https://sharepoint.stackexchange.com//questions/65621

Pergunta

Em um portal de intranet corporativa, quero permitir que qualquer visitante (qualquer usuário autenticado) personalize algumas páginas com web parts de usuário.

Quero restringir essa personalização apenas em algumas páginas.

Até agora, criei um novo nível de permissão "Personalizar webparts do usuário", que define essas permissões:

  • Adicionar e personalizar páginas
  • Adicionar/remover Web Parts pessoais
  • Atualizar Web Parts Pessoais

Este é o menor conjunto de permissões que encontro para permitir a adição de webparts de usuários.

No meu portal, tenho um "Visitante do meu portal" grupo.

Se eu aplicar a este grupo o nível de permissão personalizado (mantendo o nível de permissão de leitura OOB) no rede nível, posso adicionar web parts de usuário nas páginas.

No entanto, se eu aplicar esse nível de permissão em qualquer biblioteca da página nível ou página específica nível (quebrando a herança de permissões), não consigo adicionar webpart do usuário.

É possível aplicar essas permissões apenas em páginas específicas?

Por favor, note que eu pode remover ou atualizar webparts.Apenas a adição de webpart é restrita.

Para sua informação, as webparts são, na verdade, adicionadas por código, a partir de uma webpart "gerente" personalizada.

Especialmente, este código está lançando a exceção:

var mgr = web.GetLimitedWebPartManager(file.ServerRelativeUrl, System.Web.UI.WebControls.WebParts.PersonalizationScope.User);
var wpFile = web.GetCatalog(SPListTemplateType.WebPartCatalog).RootFolder.Files["somewebpart.webpart"];
System.Web.UI.WebControls.WebParts.WebPart newWebPart;
using (var raw = wpFile.OpenBinaryStream())
{
    using (var xr = XmlReader.Create(raw))
    {
        string error;
        newWebPart = mgr.ImportWebPart(xr, out error); 
    }
}

O ImportWebPart método está lançando alguma exceção obscura:

Microsoft.SharePoint.ApplicationRuntime.SafeControls+UnsafeControlException: A Web Part or Web Form Control on this Page cannot be displayed or imported. You don't have Add and Customize Pages permissions required to perform this action
   à Microsoft.SharePoint.WebPartPages.WebPartImporter.CreateWebPart(Boolean clearConnections)
   à Microsoft.SharePoint.WebPartPages.WebPartImporter.Import(SPWebPartManager manager, XmlReader reader, Boolean clearConnections, Uri webPartPageUri, SPWeb spWeb)
   à Microsoft.SharePoint.WebPartPages.WebPartImporter.Import(SPWebPartManager manager, XmlReader reader, Boolean clearConnections, SPWeb spWeb)
   à Microsoft.SharePoint.WebPartPages.SPWebPartManager.ImportWebPart(XmlReader reader, String& errorMessage)
   à Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager.ImportWebPart(XmlReader reader, String& errorMessage)
   à x.y.z.ImportWebPart(SPLimitedWebPartManager mgr, SPFile wpFile)

Nos logs do ULS, vejo apenas isto:

Erro ao importar WebPart.Assembly Microsoft.SharePoint, versão=14.0.0.0, Culture=neutro, PublicKeyToken=71e9bce111e9429c, TypeName.Microsoft.SharePoint.WebPartPages.ContentEditorWebPart

O que é bastante perturbador.

[Editar] Com o Reflector, encontrei no WebPartImporter.CreateWebPart método esta verificação:

     if ((!this._spWeb.AllowContributorsToEditScriptableParts && !this._spWeb.DoesUserHavePermissions(SPBasePermissions.EmptyMask | SPBasePermissions.AddAndCustomizePages)) && !this._spWeb.SafeControls.SafeAgainstScript(this._type, out unsafeErrorMessage))
        {
            throw new SafeControls.UnsafeControlException(SafeControls.UnsafeControlException.MakeGenericUnsafeExceptionMessage(unsafeErrorMessage));
        }

Na verdade, o código para adicionar uma webpart verifica a permissão no SPWeb objeto.

Devo concluir que meu cenário não é suportado?:(

Foi útil?

Solução

Depois de alguns experimentos, aqui está parece funcionar solução:

var web = SPContext.Current.Web;

var mgr = web.GetLimitedWebPartManager(file.ServerRelativeUrl, System.Web.UI.WebControls.WebParts.PersonalizationScope.User);


var wpFile = web.GetCatalog(SPListTemplateType.WebPartCatalog).RootFolder.Files["somewebpart.webpart"];



/* Elevated the process just for importing the webpart */
var elevatedWeb = GetElevatedWeb(web); // Get an elevated Web object, that points on the same web
var elevatedMgr = elevatedWeb.GetLimitedWebPartManager(file.ServerRelativeUrl, System.Web.UI.WebControls.WebParts.PersonalizationScope.User);
System.Web.UI.WebControls.WebParts.WebPart newWebPart;
using (var raw = wpFile.OpenBinaryStream())
{
    using (var xr = XmlReader.Create(raw))
    {
        string error;
        newWebPart = elevatedMgr.ImportWebPart(xr, out error); 
    }
}


/* Import the webpart, created in the elevated context, but into the current user's context. */
mgr.AddWebPart(newWebPart, "Left", 0);

Basicamente, a ideia era importar a web part em um contexto elevado, mas adicionar a web part importada no contexto atual real.

Parece funcionar, mas não sou muito fã desse mecanismo de hacking.

Outras dicas

Você deseja permitir que qualquer visitante (qualquer usuário autenticado) personalize algumas páginas com web parts de usuário...Certo?

Como fazemos isso onde trabalho, criamos um grupo que inclui as contas de todos os usuários autenticados.Podemos aplicar esse grupo de permissão em qualquer nível, documentando todo um conjunto de sites.

Espero que isso ajude você de alguma forma ...

Ao revisar o método encontrado com o refletor, parece que ele requer permissões no nível da web.Você pode querer considerar a execução do bloco com permissões elevadas, o que deve ajudá-lo a contornar a necessidade de conceder permissões no nível da web.(Supondo que esta seja uma solução de farm) Se você seguir esse caminho, considere adicionar alguma verificação lógica extra na web part do gerenciador personalizado para garantir que os privilégios elevados não estejam sendo usados/invocados incorretamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a sharepoint.stackexchange
scroll top