The Grayzone

Sharp-shooter for Silverlight - Supplying Credentials in Service

I’ve recently been using the Silverlight Report Viewer from Perpetuum Software. It’s the only real tool for viewing report services reports in Silverlight.

The Problem

Their start up example stores the report URL and data source credentials inside the web.config file. I wanted to encrypt these for added security and I also had to supply different report credentials, rather than using Windows credentials. The report credentials will be the same credentials that the user uses to login to the Silverlight application, to save them entering the credentials again.

The Code

using System.Configuration;
using System.Net;
using System.ServiceModel.Activation;
using System.Web;
using PerpetuumSoft.Reporting.Silverlight.Server.Core;
using PerpetuumSoft.Reporting.Silverlight.Server.ReportingServices;

namespace MyNamespace.Web.Services
{
  [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
  public class ReportService : MsReportServiceRemote 
  {
    protected override ICredentials GetServiceCredentials()
    {
      // Network credentials to access ReportServer
      return new NetworkCredential("username", "password");
    }

    protected override string GetServiceUrl()
    {
      // Returns url of ReportExecution2005.asmx
      return "http://127.0.0.1/ReportExecution2005.asmx";
    }

    public override ReportExecutionInfo LoadReport(string report, out ExceptionDetailBase ReportError)
    {
      // Call base.LoadReport to get ReportExecutionInfo, need this to get the DataSourceName and ExecutionID
      ReportExecutionInfo execInfo = base.LoadReport(report, out ReportError);

      if (execInfo.CredentialsRequired)
      {
        // Get users' credentials
        ReportDataSourceCredential[] credentials = new ReportDataSourceCredential[1] { 
          // Credentials for report
          new ReportDataSourceCredential
          {
            DataSourceName = execInfo.DataSourcePrompts[0].Name,
            UserName = "username",
            Password = "password"
          } 
        };

        // Set the data source credentials for report
        this.SetDataSourcesCredentials(execInfo.ExecutionID, credentials, out ReportError);
      }

      return execInfo;
    }
  }
}

Key Points

  1. Firstly override the GetServiceCredentials() and GetServiceUrl() methods and supply the required details, this saves putting these details into the web.config file.
  2. Override the LoadReport() method. The first thing we do in here is call base.LoadReport() as this gives us a ReportExecutionInfo object. We use this to get the DataSourceName, used when setting up the ReportDataSourceCredential object, and also the ExecutionID, which we use to call the SetDataSourcesCredentials method.

Share this: