Browse DevX
Sign up for e-mail newsletters from DevX


Building Report-enabled Applications with the New ReportViewer Controls (Part 2 of 2) : Page 4

Organizations can use Reporting Services to make data easily accessible to internal users, customers, and partners. The second part of this article shows you how you can leverage the Web version of the ReportViewer control to integrate Reporting Services 2005 with your intranet and Internet applications—without compromising security.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Custom security
Custom security is more flexible than trusted subsystem but it is more difficult to implement and configure because it requires writing a custom security extension. Consider custom security when you need to get the best of both worlds—application based security to authenticate and authorize the users with the ability to pass the user identity to the report server. With custom security, the Web application handles the user authentication and authorization as usual. At some point (e.g. when the user log in), the application calls the LogonUser SOAP API to authenticate the user against the Report Server and obtain an authentication ticket in the form of a cookie. For more information about custom security, read the article "Harden MS Reporting Services Using Custom Extensions."

Tip: If the Web application uses the ASP.NET Forms Authentication, it is possible to reuse the authentication ticket by following the instructions in the Forms Authentication Across Applications article. This is the approach I followed in the WebReporter demo. When testing the application on your local computer, make sure to launch your application using the machine name, e.g. http://<mymachinename>/WebReporter/default.aspx. If you use localhost, the browser will not pass the cookie to the Report Server). This easy-to-overlook gotcha can cause you countless hours of debugging and head scratching.

After setting the Report Server up for custom security, follow these steps to re-configure the WebReporter demo:

In the application Web.config file, comment the <authentication mode="Windows"/> and <identity impersonate="true"/> elements to disable Windows authentication.

Again in Web.config, enable Forms Authentication by enabling the settings in the Custom Security block (authentication, identity, and machineKey). After you enable these settings, the application will automatically redirect you to the Login.aspx page when you request the default.aspx page.

In the default.aspx code-behind page, enable the following line

reportViewer.ServerReport.ReportServerCredentials = new MyReportServerCredentials();

The Web ReportViewer handles security somewhat differently than the WinForms ReportViewer. Specifically, you need assign an instance of a class that implements the Microsoft.Reporting.WebForms.IReportServerCredentials interface to the ReportServerCredentials property. The IReportServerCredentials interface defines two properties and one method whose purpose is explained in Table 3.

Table 3. IReportServerCredentials Interface: The table lists the properties and methods of the IReportServerCredentials interface.
Property/Method Returns Use When
ImpersonationUser property WindowsIdentity or null to ignore You need to programmatically impersonate the user request to go under a specific Windows account, e.g. when you need more control when implementing the trusted subsystem scenario.
NetworkCredentials property ICredentials or null to ignore Similar to the ReportServerCredentials.NetworkCredentials of the WinForms ReportViewer, use this property for Basic authentication.
GetFormsCredentials method Authentication ticket (cookie) oruser/password/domain You need to configure the ReportViewer with custom security.

Based on your security requirements, you may need to implement only one IReportServerCredentials property (method). For example, if you need to integrate the Web ReportViewer with custom security, you need to implement GetFormsCredentials only; ImpersonationUser and NetworkCredentials should return null. As with the WinForms ReportViewer, for optimum performance, the Web ReportViewer caches the IReportServerCredentials results. For example, if you use custom security, the Web ReportViewer invokes GetFormsCredentials the first time it's initialized. Behind the scenes, the control will invoke LogonUser and cache the authentication ticket. Subsequent report requests on the same page, such as those stemming from interactive features will use the cached authentication ticket.

If your application uses ASP.NET Forms Authentication, implementing GetFormsCredentials is remarkably simple.

public bool GetFormsCredentials (out Cookie authCookie, out string user, out string password, out string authority) { user = password = authority = null; // The cookie name is specified in the <forms> element in Web.config (.ASPXAUTH by default) HttpCookie cookie = HttpContext.Current. Request.Cookies[".ASPXAUTH"]; if (cookie == null) HttpContext.Current.Response. Redirect("login.aspx"); Cookie netCookie = new Cookie( cookie.Name, cookie.Value); if (cookie.Domain == null) { netCookie.Domain = HttpContext.Current.Request. ServerVariables["SERVER_NAME"].ToUpper(); } netCookie.Expires = cookie.Expires; netCookie.Path = cookie.Path; netCookie.Secure = cookie.Secure; authCookie = netCookie; return true; }

First, the code sets the user, password, and authority output arguments to null because we will use the authentication ticket returned by the ASP.NET Forms Authentication infrastructure. Alternatively, if you prefer to work with user credentials, you could set the authCookie argument to null and use the user credentials for authentication. As I mentioned in the first part of this article, caching the user credentials may present a security risk and it should be avoided whenever possible.

Next, the code assumes that the user has already logged in to the application and the ASP.NET Forms authentication ticket is already generated. If this is not the case, the code redirects the user to the login page. If the cookie is present, the only task left is to convert the cookie to a System.Net.Cookie and pass it back to the ReportViewer.

Author's Note: Passing the authentication ticket from the Web application to the Report Server could be more involved. For example, if both applications are on different domains, the browser will refuse to pass the cookie for security reasons. Trying to change the cookie domain name in GetFormsCredentials won't help in this case. One workaround is to make the LogonUser call from a page on the Report Server machine so the authentication ticket is bound to the Report Server domain.

Thanks for your registration, follow us on our social networks to keep up-to-date