Question

J'ai un rapport enregistré sur un serveur de rapports SQL2005 et je souhaite renvoyer un fichier PDF rendu de ce rapport. Je l'ai compris lorsque je travaillais avec un fichier * .rdlc local ( et j'ai blogué à ce sujet ), mais pas lorsque * .rdl réside sur un serveur de génération de rapports. Je reçois une erreur 401 non autorisée à la ligne ...

.
reportViewer.ServerReport.SetParameters(reportDefinition.ReportParameters);

Voici la méthode utilisée pour rendre le rapport.

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;
}

L’autre élément qui vous manque est la classe 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);
    }
}

Autres choses à savoir.

  • Ceci s'exécute sur un intranet et l'emprunt d'identité est activé.
  • La journalisation indique que l'utilisateur de l'emprunt d'identité est défini correctement.
  • Cela fonctionne lorsqu'il est exécuté dans Visual Studio ( http: // localhost: devport ), et il fonctionne lorsqu'il est exécuté sous mon zone de développement ( http: // localhost / myApplication ). Cela ne fonctionne pas lors de l'exécution sur nos serveurs de test ou de production.
  • J'ai essayé des solutions avec et sans les paramètres system.net.defaultProxy dans web.config. Ni travaillé.

Qu'est-ce que je fais mal? Est-ce un paramètre de serveur? Est-ce le code? Est-ce web.config?

Était-ce utile?

La solution

Nous avons enfin résolu le problème. Nos administrateurs réseau ont désactivé le double saut. Ainsi, alors que l'emprunt d'identité se connectait correctement en tant que domain \ jmeyer , l'application tentait toujours de se connecter à la zone SRS avec domain \ web01 $ . Pourquoi est-ce mis en place comme ça? Parce que le double saut est une énorme faille de sécurité. (Ou alors on m'a dit. Cela ressemble-t-il à quelque chose que vous liriez sur Le WTF quotidien ?)

Notre solution a été de créer un utilisateur générique domain \ ssrs_report_services et de vous connecter à cet utilisateur avec les informations d'identification réseau suivantes

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") ; }
    }    
}

L’exemple ci-dessus est l’exemple classique de solution que vous pouvez trouver partout sur Internet.

Autres conseils

" Double saut " est autorisé - avec l'authentification Kerberos ... (tant qu'il fonctionne correctement!)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top