Pregunta

Tengo un informe guardado en un servidor de informes SQL2005 y quiero devolver un PDF representado de este informe. Lo descubrí cuando trabajé con un archivo local * .rdlc ( y he blogueado al respecto ), pero no cuando el * .rdl reside en un servidor de informes. Recibo un error 401 no autorizado en la línea ...

reportViewer.ServerReport.SetParameters(reportDefinition.ReportParameters);

Aquí está el método utilizado para representar el informe.

public byte[] Render(IReportDefinition reportDefinition)
{
    var reportViewer = new ReportViewer();
    byte[] renderedReport;
    try
    {
        var credentials = new WindowsImpersonationCredentials();
        reportViewer.ServerReport.ReportServerUrl = new Uri("http://myssrsbox", UrlKind.Absolute);
        reportViewer.ServerReport.ReportServerCredentials = credentials;
        reportViewer.ServerReport.ReportPath = reportDefinition.Path;
        // Exception is thrown on the following line...
        reportViewer.ServerReport.SetParameters(reportDefinition.ReportParameters);

        string mimeType;
        string encoding;
        string filenameExtension;
        string[] streams;
        Warning[] warnings;

        renderedReport = reportViewer.ServerReport.Render(reportDefinition.OutputType, reportDefinition.DeviceInfo, out mimeType, out encoding, out filenameExtension, out streams, out warnings);
    }
    catch (Exception ex)
    {
        // log the error...
        throw;
    }
    finally
    {
        reportViewer.Dispose();
    }
    return renderedReport;
}

La otra cosa que te falta es la clase WindowsImpersonationCredentials.

public class WindowsImpersonationCredentials : IReportServerCredentials
{
    public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority)
    {
        authCookie = null;
        userName = password = authority = null;
        return false;
    }

    public WindowsIdentity ImpersonationUser
    {
        get { return WindowsIdentity.GetCurrent(); }
    }

    public ICredentials NetworkCredentials
    {
        get { return null; }
    }

    public override string ToString()
    {
        return String.Format("WindowsIdentity: {0} ({1})", this.ImpersonationUser.Name, this.ImpersonationUser.User.Value);
    }
}

Otras cosas que puede necesitar saber ...

  • Esto se está ejecutando en una intranet y la suplantación está activada.
  • El registro indica que el usuario de suplantación se está configurando correctamente.
  • Este funciona cuando se ejecuta en Visual Studio ( http: // localhost: devport ), y funciona cuando se ejecuta en mi cuadro de desarrollo ( http: // localhost / myApplication ). no funciona cuando se ejecuta en nuestros servidores de prueba o producción.
  • He probado soluciones con y sin configuración de system.net.defaultProxy en web.config. Ninguno funcionó.

¿Qué estoy haciendo mal? ¿Es una configuración de servidor? ¿Es código? ¿Es web.config?

¿Fue útil?

Solución

Finalmente resolvimos el problema. Nuestros administradores de red han deshabilitado el doble salto, por lo que mientras la suplantación se conectaba correctamente como domain \ jmeyer , la aplicación aún intentaba conectarse al cuadro SRS con domain \ web01 $ . ¿Por qué está configurado así? Porque el doble salto es un agujero de seguridad masivo. (O eso me dijeron. ¿Suena como algo que leerías en The Daily WTF ?)

Nuestra solución fue crear un usuario genérico de dominio \ ssrs_report_services y conectarnos con ese usuario con las siguientes credenciales de red

public class CustomCredentials : IReportServerCredentials
{
    public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority)
    {
        authCookie = null;
        userName = password = authority = null;
        return false;
    }

    public WindowsIdentity ImpersonationUser
    {
        get { return null; }
    }

    public ICredentials NetworkCredentials
    {
        get { return new NetworkCredential("ssrs_report_services", "password", "domain") ; }
    }    
}

Lo anterior es la solución de ejemplo clásica que puedes encontrar en todas las redes.

Otros consejos

" Salto doble " está permitido, con autenticación Kerberos ... (siempre y cuando funcione correctamente)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top