ReportViewer - Passing Credentials to a Report Server

Posted Tuesday, October 10, 2006 2:13 PM by C-Dog's .NET Tip of the Day

The reason I write this today is that the documentation is completely 100% worng on how to do that in MSDN. It has you set properties that are get only, etc. So here is how to do it since it took me a while to figure out.

So you've built that fancy new report and you want to integrate it into an existing web application, now what? Well you have a couple of options, call the reporting web service or use the ReportViewer control. If you are using the ReportViewer control, it can operate in two modes, local or remote. In local mode, you can access a report rdl file right off the web server and display it. Ideally, though you will use a remote reporting server. By default, this uses the credentials of the current logged in user or the NETWORK SERVICE account if you are not using windows authentication.

If you are not using Windows Authentication, that means you have to pass credentials to the report server programmatically. First, determine the account you want to use and assign that account the Browser role inside Reporting Services. Assign any other folder level permission that are necessary to access the report.

After you have an account set up, you have to add some statements to the code behind of your page in the OnLoad method or wherever appropriate. Before you start be sure and add a using statement for Microsoft.Reporting.WebForms. You may need to add this as a reference to your project first. To set credentials, you access the ServerReport.ReportServerCredentials of the ReportViewer control. The problem is this property only accepts the interface IReportServerCredentials. There is no class out of the box to assign to this. That means you have to create one of your own.

So now you have to create a custom class that implements Microsoft.Reporting.WebForms.IReportServerCredentials. Basically it just manipulates a typical NetworkCredentials class and adds a method. When it comes time to implement it, just copy and paste the class below. You can put it in App_Code, or if you have a class library you can put it wherever in there as long as it references Microsoft.Reporting.

using System;
using System.Data;
using System.Configuration;
using System.Net;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Microsoft.Reporting.WebForms;

/// 
/// Summary description for CustomReportCredentials
/// 
public class CustomReportCredentials : 
Microsoft.Reporting.WebForms.IReportServerCredentials
{

    // local variable for network credential.
    private string _UserName;
    private string _PassWord;
    private string _DomainName;
    public CustomReportCredentials(string UserName, string PassWord, 
string DomainName)
    {
        _UserName = UserName;
        _PassWord = PassWord;
        _DomainName = DomainName;
    }
    public WindowsIdentity ImpersonationUser
    {
        get
        {
            return null;  // not use ImpersonationUser
        }
    }
    public ICredentials NetworkCredentials
    {
        get
        {

            // use NetworkCredentials
            return new NetworkCredential(_UserName, 
_PassWord, _DomainName);
        }
    }
    public bool GetFormsCredentials(out Cookie authCookie, 
out string user, out string password, out string authority)
    {

        // not use FormsCredentials unless you have 
implements a custom autentication.
        authCookie = null;
        user = password = authority = null;
        return false;
    }
}

Now that you have your custom credentials class, you need to pass the credentials to your ReportViewer control. The code below passes a username, password, and domain the reporting server.

EventReportViewer.ServerReport.ReportServerCredentials
= new CustomReportCredentials("MyUserName", "MyPassword", "MyDomain");

Ideally, you would have those credentials stored some place securely. That sounds like a lot but its really not too bad. Luckily, I did all the hard research to figure it out for you so you don't have to.

Read the complete post at http://www.dotnettipoftheday.com/blog.aspx?id=312