Olá pessoal,
Boa noite.
Neste post, vou demonstrar como resolver um problema muito estranho no SQL Server Reporting Services 2016, que ocorre quanto estava tentando apagar alguns relatório móveis e recebia essa mensagem de erro:
Erro ao invocar a extensão de autorização.
Como essa mensagem não é nem um pouco explicativa, resolvi tentar analisar os arquivos de log do Reporting Services (geralmente localizado em “C:\Program Files\Microsoft SQL Server\MSRS13.Sua_Instancia\Reporting Services\LogFiles”) para tentar identificar alguma dica da origem do problema, mas encontrei a seguinte mensagem em um dos arquivos:
Microsoft.ReportingServices.Portal.WebHost!library!b!12/02/2016-14:22:00:: e ERROR: Throwing Microsoft.ReportingServices.Diagnostics.Utilities.AuthorizationExtensionException: , Microsoft.ReportingServices.Diagnostics.Utilities.AuthorizationExtensionException: Erro ao invocar a extensão de autorização. —> System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.ReportingServices.Authorization.SdAndType.GetRightSecDesc(SecurityItemType crtItemType, Hashtable secDescHash, Byte[]& primSecDesc, Byte[]& secSecDesc)
at Microsoft.ReportingServices.Authorization.WindowsAuthorization.InnerCheckAccess(String userName, IntPtr userToken, SecurityItemType itemType, Byte[] secDesc, UInt32& rightsMask, ReportSecDescType rptSecDescType)
at Microsoft.ReportingServices.Authorization.WindowsAuthorization.<>c__DisplayClassa.<CheckAccess>b__9()
at Microsoft.ReportingServices.Diagnostics.RevertImpersonationContext.<>c__DisplayClass1.<Run>b__0(Object state)
at System.Security.SecurityContext.Run(SecurityContext securityContext, ContextCallback callback, Object state)
at Microsoft.ReportingServices.Diagnostics.RevertImpersonationContext.Run(ContextBody callback)
at Microsoft.ReportingServices.Authorization.WindowsAuthorization.CheckAccess(String userName, IntPtr userToken, Byte[] secDesc, FolderOperation requiredOperation)
at Microsoft.ReportingServices.Library.Security.<>c__DisplayClass1f.<CheckAccess>b__1c()
at Microsoft.ReportingServices.Diagnostics.ExtensionBoundary.Invoke(Method m)
Como vocês notaram, a mensagem de erro não estava muito clara.. Resolvi tentar abrir o relatório na ferramenta Microsoft SQL Server Mobile Report Publisher, e aparecia a mensagem de erro abaixo:
Eu imagino que esse problema ocorreu porque haviam relatórios utilizando um determinado dataset, que foi apagado sem ser removido do relatório antes (A ferramenta não deveria permitir a exclusão caso haja dependências).
Resolvendo o problema e apagando os arquivos
Como não consegui nenhuma solução utilizando as ferramentas gráficas, resolvi tentar resolver isso pelo banco de dados, conectando na instância onde o Reporting Services estava instalado e acessando o database ReportServer.
Para quem nunca utilizou esse database, as 2 principais tabelas são:
– Datasets: Tabela que guarda os relacionamentos entre os datasets e os relatórios.
– Catalog: Tabela que guarda os relatórios e toda a estrutura e organização dos objetos do Reporting Services. É a principal tabela de conteúdo.
Como haviam vários relatórios com esse problema, onde eu não conseguia exclui-los, eu os movi para uma pasta chamada “Lixo” e executei as queries abaixo:
1 2 3 4 5 6 7 8 |
DELETE A FROM ReportServer.dbo.DataSets A JOIN ReportServer.dbo.[Catalog] B ON A.ItemID = B.ItemID WHERE [Path] LIKE '%Lixo%'; DELETE FROM ReportServer.dbo.[Catalog] WHERE [Path] LIKE '%Lixo%'; |
Com isso, a pasta “Lixo” e todos os objetos dentro dela foram apagados no banco de dados com sucesso e deixaram de aparecer no Portal Web do Reporting Services.
Solução manual: Editando o arquivo do relatório
Uma outra solução para isso seria baixar o arquivo do relatório e extrai-lo para uma pasta (igual você faz com um arquivo ZIP). Abrindo essa pasta, você irá encontrar o arquivo sources.xml, que contém os datasets utilizados pelo relatório.
O arquivo deverá ter um conteúdo parecido com esse:
1 2 3 4 |
<DataSources> <Shared Guid="5430d1fe-c55a-4540-9a6a-d96ca2a39e67" Name="Dataset" WorksheetIndex="0" ServerUri="http://localhost:80/relatorios/" DataItemLocation="/Dataset" Hash="" /> <Shared Guid="8ea514dc-fc9f-47cf-9fd2-f9e546c4e075" Name="Dataset2" WorksheetIndex="1" ServerUri="http://localhost:80/relatorios/" DataItemLocation="/Dataset2" Hash="" /> </DataSources> |
Edite também o arquivo metadata.xml, onde esse trecho do arquivo é o que nos interessa:
1 2 3 4 5 6 7 8 9 10 11 12 |
<dataSets> <dataSet name="Dataset" type="Shared" mrp:DataSourceType="Shared" mrp:Server="http://localhost:80/relatorios/" mrp:OriginalWorksheet="" mrp:OriginalWorksheetIndex="0" mrp:OriginalPath="" mrp:OriginalUser=""> <id>5430d1fe-c55a-4540-9a6a-d96ca2a39e67</id> <path>/Dataset</path> <isParameterized>false</isParameterized> </dataSet> <dataSet name="Dataset2" type="Shared" mrp:DataSourceType="Shared" mrp:Server="http://localhost:80/relatorios/" mrp:OriginalWorksheet="" mrp:OriginalWorksheetIndex="1" mrp:OriginalPath="" mrp:OriginalUser=""> <id>8ea514dc-fc9f-47cf-9fd2-f9e546c4e075</id> <path>/Dataset2</path> <isParameterized>false</isParameterized> </dataSet> </dataSets> |
Agora edite o arquivo definition.xml, que contém todos os objetos que compõem o relatório, e procure todos objetos onde o input seja o nome do dataset excluído. O trecho que estamos analisando, são os nós descendentes da tag <Elements>, e tem essa estrutura:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<GalleryElement Name="SimpleDataGrid" Type="Microsoft.ReportingServices.MobileReportPublisher.Gallery.SimpleDataGrid, Microsoft.ReportingServices.MobileReportPublisher.Gallery, Version=1.0.3895.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" Accent="False" AggregateByCategory="False" AggregateByTime="False" RowNumbers="Auto"> <SchemaItem Id="Data" Input="Dataset2" AggregationRule="None" Filters="" /> <Title>Grade de dados simples 1</Title> <SubTitle></SubTitle> <ColumnDefinitions> <GridViewTextColumnDefinition Title="instance_id" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="instance_id" StringFormat="General" /> <GridViewTextColumnDefinition Title="job_id" ColumnType="Text" IsVisible="True" ValueColumn="job_id" /> <GridViewTextColumnDefinition Title="step_id" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="step_id" StringFormat="General" /> <GridViewTextColumnDefinition Title="step_name" ColumnType="Text" IsVisible="True" ValueColumn="step_name" /> <GridViewTextColumnDefinition Title="sql_message_id" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="sql_message_id" StringFormat="General" /> <GridViewTextColumnDefinition Title="sql_severity" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="sql_severity" StringFormat="General" /> <GridViewTextColumnDefinition Title="message" ColumnType="Text" IsVisible="True" ValueColumn="message" /> <GridViewTextColumnDefinition Title="run_status" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="run_status" StringFormat="General" /> <GridViewTextColumnDefinition Title="run_date" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="run_date" StringFormat="General" /> <GridViewTextColumnDefinition Title="run_time" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="run_time" StringFormat="General" /> <GridViewTextColumnDefinition Title="run_duration" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="run_duration" StringFormat="General" /> <GridViewTextColumnDefinition Title="operator_id_emailed" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="operator_id_emailed" StringFormat="General" /> <GridViewTextColumnDefinition Title="operator_id_netsent" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="operator_id_netsent" StringFormat="General" /> <GridViewTextColumnDefinition Title="operator_id_paged" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="operator_id_paged" StringFormat="General" /> <GridViewTextColumnDefinition Title="retries_attempted" ColumnType="Number" AggregationType="None" IsVisible="True" ValueColumn="retries_attempted" StringFormat="General" /> <GridViewTextColumnDefinition Title="server" ColumnType="Text" IsVisible="True" ValueColumn="server" /> </ColumnDefinitions> </GalleryElement> |
Por último, dentro da pasta “data”, apague o arquivo .json cujo título é o nome do dataset excluído. Agora salve tudo de volta no arquivo .RSMOBILE que você baixou e editou e abra esse arquivo no Mobile Report Publisher.
Pronto. Seu relatório está abrindo novamente, sem o dataset excluído. Você já pode publicá-lo novamente.
Espero que tenham gostado do post e até mais.
Thank you!