Thursday 19 February 2009

Securing Reporting Services Web Services.

 

Many web based applications use reporting services to facilitate report production. We have used them extensively in many of our internal and external applications. The main drivers for deployment have been:
  • to produce PDF and other format documents
  • they are part of SQL Server
  • they have a very simple and effective deployment model
Although placing reporting services behind a second level of firewalls will secure it from external attack a mechanism is required to authenticate the client – otherwise internal users will be able to run any reports. To this end we would normally create a domain or local NT account and grant that account read access to the applications. These credentials can then be used to authenticate when using web services to execute reports.
However, when using the Microsoft ReportViewer web control it is not at first clear how to set the network credentials to call reporting services.
In order to set the credentials you must first create a class that implements the IReportServerCredentials interface as follows –
[Serializable]
    public class RsCredentials : IReportServerCredentials
    {
        #region IReportServerCredentials Members
 
        public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority)
        {
            authCookie = new Cookie();
            userName = password = authority = null;
            return false;
        }
 
        public System.Security.Principal.WindowsIdentity ImpersonationUser
        {
            get { return null; }
        }
 
        public ICredentials NetworkCredentials
        {
            get
            {
                if (ConfigurationManager.AppSettings["rptUser"] != null)
                {
                    return new NetworkCredential(
                            ConfigurationManager.AppSettings["rptUser"],
                            ConfigurationManager.AppSettings["rptPassword"]);
                }
                else
                {
                    return CredentialCache.DefaultNetworkCredentials;
                }
            }
          
        }
 
        #endregion
    }
 
And set the report viewer report server to use these credentials.
 
m_rptViewer.ServerReport.ReportServerCredentials = new RsCredentials();
 
In this particular implementation we look for a username and password in the web.config or we use the current Network Credentials of the process.
The current network credentials can be used if you are running if your asp.net worker process is running with account credentials that have access to the reports. Most internet setups do not usually use or allow domain authentication in the web servers so in practice this mechanism is rarely used.