Reporting Services and the intarweb
Windows Server 2008, SQL Server 2008, IIS7 and Reporting Services 2008 - latest and greatest, made for each other. ASP.NET developed using Visual Studio 2008, showing the reports in the Microsoft supplied ReportViewer web control.
"Oh, that's easy!" said the documentation. "You just use the ReportViewer control. The server-side part of it acts as a proxy that runs in the process of your ASP.NET application's AppPool, so you just need to give database permissions to the AppPool user and Bob's your uncle."
Bollocks. There are two other steps, both of which are poorly documented and neither of which is self-evident.
Handler mappings
First you have to set up a handler mapping so that Reporting Services gets first crack at AXD requests. Start the IIS Manager,select the server node and double click this icon:
t
Now click Add Managed Handler... (it will be at top right) to get the dialog shown below, and fill in the blanks. There maybe several ReportViewer web form HttpHandlers; pick the version appropriate to your web app (probably the most recent).

Having set this up, select the web in which you want ReportViewer to work and again double click on the Handler Mappings icon. The handler will appear, but it will be greyed-out. Enable it by double clicking on it and ticking execute in the dialog that appears. Repeat and rinse for any other affected web apps. Once you've done this you stand a snowball's chance in hell of getting it to work.
The next step is to provide credentials. If the report server and your ASP.NET applications live on the same box, you can specify http://localhost/ReportServer and you won't have to supply credentials.
Specifying credentials
You do this by implementing IReportServerCredentials. Here's a deliberately simplified example.
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;
[Serializable]
public sealed class MyReportServerCredentials : IReportServerCredentials
{
public WindowsIdentity ImpersonationUser
{
get
{
// Use the default Windows user. Credentials will be
// provided by the NetworkCredentials property.
return null;
}
}
public ICredentials NetworkCredentials
{
get
{
//please don't hard code this
return new NetworkCredential("userName", "password", "NT domain");
}
}
public bool GetFormsCredentials(out Cookie authCookie,
out string userName, out string password,
out string authority)
{
authCookie = null;
userName = null;
password = null;
authority = null;
// Not using form credentials
return false;
}
}
Once you've set this up you are in a position to control the credentials presented to reporting services on the basis of the forms authentication identity — per user rather than per application. Here's how you get the report viewer control to use your implementation of IReportServerCredentials:
protected void Page_Load(object sender, EventArgs e)
{
ReportViewer1.ServerReport.ReportServerCredentials = new MyReportServerCredentials();
}