Como o ReportManager pode usar uma porta diferente externamente do que por trás do firewall?

2

Estou no SSRS 2012 no modo nativo. A configuração não parece ter mudado muito do SSRS 2008, do qual fiz a atualização, portanto, o problema se aplica a ambas as versões (no entanto, se houver uma solução, ela poderá ou não se aplicar a ambas).

Estou em uma situação em que gostaria de disponibilizar o site do ReportManager a partir de um conjunto de portas no lado externo de um firewall, mas, internamente, tenho a configuração do SSRS em uma porta diferente. Alguém sabe como isso pode ser feito?

Detalhes

O motivo de ser um problema é porque o código do SSRS insiste na construção de URLs completas e absolutas para os diferentes locais dentro do site do ReportManager. (IMO, essa é apenas uma das muitas falhas de design significativas / incapacitantes no SSRS) Se fosse usada apenas URLs que não tentassem especificar o domínio + porta, isso não seria um problema.

Exemplo

Vamos começar com um URL externo de " link ", e o ReportManager está configurado para funcionar na porta 8080 (seu port forward go da porta 80 para 8088, é claro). Se você for para o URL externo, você acessará o site muito bem; vamos ignorar o subsistema AuthC e assumir que você logou em OK. Para alguns dos links (por exemplo, "Visualização de Detalhes", "Mover", "Excluir", etc.), agora, você não irá onde esperava, porque o SSRS tenta enviar você para " link ...". Você pode corrigir manualmente o link removendo a porta e chegará à página. Existem diferenças em quais URLs são quebrados entre o SSRS 2012 e o SSRS 2008, mas o problema ainda está lá.

    
por Granger 13.06.2013 / 17:59

1 resposta

1

Eu tenho algo que funciona no SSRS 2012, mas é um hack total. É possível usar o Javascript do lado do cliente para reescrever todas as URLs (mais o ocasional parâmetro RedirectUrl do SSRS), mas isso não leva em conta as chamadas Response.Redirect () do lado do servidor. Então você ficaria com uma solução parcial.

Em suma, adicione um HttpModule ao ReportManager para adicionar um manipulador de eventos PreRequestHandlerExecute. Dentro dele, use Reflection para corrigir GlobalApp.BaseUrl e Request.Url para sair do cabeçalho HOST em vez do padrão. Você precisa alterar ambos porque o SSRS nem sempre usa seu próprio BaseUrl ao criar links. (Eu usei o ILSpy para encontrar os campos a serem alterados.)

Aqui é meu. Tenho certeza de que poderia ser feito melhor, mas o que eu tenho funciona e eu realmente não me importo mais. Trabalhar no SSRS tem um jeito de sugar a vontade de viver de você.

EDITAR : Corrigida a parte que modifica Request.Url. Observe que, embora esteja especificando .Fragment, o cliente não envia isso, portanto, está sempre em branco.

void context_PreRequestHandlerExecute(object sender, EventArgs ea)
{
    HttpApplication app = sender as HttpApplication; // also at: HttpContext.Current.ApplicationInstance
    string host = app.Context.Request.Headers["HOST"];
    if (!string.IsNullOrEmpty(host))
    {
        System.Reflection.FieldInfo fi = typeof(Microsoft.ReportingServices.UI.GlobalApp).GetField("m_baseUrl", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        if (fi != null)
        {
            string protocol = "http://";
            if (app.Context.Request.IsSecureConnection)
                protocol = "https://";
            Uri url = new Uri(string.Format("{0}{1}{2}", protocol, host, app.Context.Request.ApplicationPath));
            fi.SetValue(app as Microsoft.ReportingServices.UI.GlobalApp, url);

            fi = typeof(System.Web.HttpRequest).GetField("_url", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            if (fi != null)
            {
                url = new Uri(string.Format("{0}{1}{2}{3}{4}", protocol, host, app.Context.Request.FilePath, app.Context.Request.Url.Query, app.Context.Request.Url.Fragment));
                fi.SetValue(app.Context.Request, url);
            }
        }
    }
}
    
por 15.06.2013 / 03:18