The IReportServerCredentials approach with the ReportViewer control is working fine within a domain, but I get a 401 not authorized error for a Web IIS server trying to call a SSRS server in another domain. I've see plenty of helpful postings on the use of IReportServerCredentials but nothing that provides suggestions for this cross domain issue.
Using VS 2008 VB.NET web app with ReportViewer control Version=8.0.0.0.
Outside domainA Web Server IIS 8. OS = Windows NT 6.2;
Inside domainA Windows 7 desktop; Inside domainA Windows Server 2003
SSRS using windows authentication and on SQL Server 2012. OS = Windows NT 6.2
The processing described below successfully produces a report when the web server app runs on a machine in the same domain as the SSRS server. For the "same domain" web app, both Win 7 desktop VS 2008 development server and Windows 2003 IIS 6 have been tested successfully.
The report fails with error "The request failed with HTTP status 401: not authorized " when the web app is run from a windows IIS 8 machine (outward or Internet facing web server) that is not in the domain of the SSRS server. The ReportViewer control credentials (provided by IReportServerCredentials and taken from the web.config file) match a domain account in the same domain as the SSRS server and one that has browser permission on the report folder. The same credentials are used successfully for reports requested from within the SSRS domain.
One interesting thing is that on the Internet facing web server, I can access the report via a browser request. So it is possible to have a user request coming from the Internet facing machine get through the SSRS windows authentication. Just does not work for the ReportViewer.
Using IReportServerCredentials interface per example provided by Microsoft.
IReportServerCredentials would appear to be a good approach because it can pass credentials of a windows account known to the SSRS server, but not known to the client machine. By the way, database calls to SQL Server in domainA using a SQL Server native login account work fine. So the network supports communication to a domain that the web server does not belong to.
<Serializable()> _
Public NotInheritable Class MyReportServerCredentials
Implements IReportServerCredentials
Public ReadOnly Property ImpersonationUser() As System.Security.Principal.WindowsIdentity _
Implements IReportServerCredentials.ImpersonationUser
Get
'Use the default windows user. Credentials will be
'provided by the NetworkCredentials property.
Return Nothing
End Get
End Property
Public ReadOnly Property NetworkCredentials() As ICredentials _
Implements IReportServerCredentials.NetworkCredentials
Get
'Read the user information from the web.config file.
'By reading the information on demand instead of storing
'it, the credentials will not be stored in session,
'reducing the vulnerable surface area to the web.config
'file, which can be secured with an ACL.
'User name
Dim userName As String = _
ConfigurationManager.AppSettings("MyReportViewerUser")
If (String.IsNullOrEmpty(userName)) Then
Throw New Exception("Missing user name from web.config file")
End If
'Password
Dim password As String = _
ConfigurationManager.AppSettings("MyReportViewerPassword")
If (String.IsNullOrEmpty(password)) Then
Throw New Exception("Missing password from web.config file")
End If
'Domain
Dim domain As String = _
ConfigurationManager.AppSettings("MyReportViewerDomain")
If (String.IsNullOrEmpty(domain)) Then
Throw New Exception("Missing domain from web.config file")
End If
Return New NetworkCredential(userName, password, domain)
End Get
End Property
Public Function GetFormsCredentials(ByRef authCookie As Cookie, _
ByRef userName As String, _
ByRef password As String, _
ByRef authority As String) As Boolean _
Implements IReportServerCredentials.GetFormsCredentials
authCookie = Nothing
userName = Nothing
password = Nothing
authority = Nothing
'Not using form credentials
Return False
End Function
End Class
'Set the ReportViewer values and retrieve the report from the SSRS server into a pdf file on the client machine.
ProposalRptViewer.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Remote
' Set the ReportViewer ReportServerCredentials from the MyReportServerCredentials Class.
' Note the credentials are for a domain account defined in the same domain that the SSRS server belongs to and one that has browser permission on the report folder.
ProposalRptViewer.ServerReport.ReportServerCredentials = _
New MyReportServerCredentials()
ProposalRptViewer.ServerReport.ReportServerUrl = New Uri(System.Configuration.ConfigurationManager.AppSettings(Web.[Global].CfgKeyReportServerURL))
ProposalRptViewer.ServerReport.ReportPath = System.Configuration.ConfigurationManager.AppSettings(Web.[Global].CfgKeyReportPathProposal)
ProposalRptViewer.ShowCredentialPrompts = False ' disable prompting for data source credentials
Dim paramList As New Generic.List(Of ReportParameter)
Dim pInfo As ReportParameterInfoCollection
pInfo = ProposalRptViewer.ServerReport.GetParameters()
paramList.Add(New ReportParameter("ProposalID", ProposalID, True))paramList.Add(New ReportParameter("Entity", Entity, True))
paramList.Add(New ReportParameter("intRatesPage", intRatesPage1, True))
ProposalRptViewer.ServerReport.SetParameters(paramList)
' Process and render the report
ProposalRptViewer.ServerReport.Refresh()
Dim mimeType As String = Nothing
Dim encoding As String = Nothing
Dim streams As String() = Nothing
Dim extension As String = Nothing
Dim warnings As Microsoft.Reporting.WebForms.Warning() = Nothing
Dim returnValue As Byte()
' Render the proposal Rate Page 1 report to a Byte Array output in pdf file format.
returnValue = ProposalRptViewer.ServerReport.Render("PDF", Nothing, mimeType, encoding, extension, streams, warnings)
Error only occurs for web server not in domain of SSRS Server:
The request failed with HTTP status 401: Unauthorized. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Net.WebException: The request failed with HTTP status 401: Unauthorized.
Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. Stack Trace:
[WebException: The request failed with HTTP status 401: Unauthorized.] Microsoft.SqlServer.ReportingServices2005.Execution.RSExecutionConnection.GetSecureMethods() +236 Microsoft.SqlServer.ReportingServices2005.Execution.RSExecutionConnection.IsSecureMethod(String methodname) +58 Microsoft.SqlServer.ReportingServices2005.Execution.RSExecutionConnection.SetConnectionSSLForMethod(String methodname) +16 Microsoft.SqlServer.ReportingServices2005.Execution.RSExecutionConnection.LoadReport(String Report, String HistoryID) +226 Microsoft.Reporting.WebForms.ServerReport.GetExecutionInfo() +192 Microsoft.Reporting.WebForms.ServerReport.SetParameters(IEnumerable`1 parameters) +136 DeltaRater.Web.ViewRates.btnCreateProposal_Click(Object sender, EventArgs e) in C:\alex\~~_____Rapid_Rater\SourceDir_VS2008_Jan17_2014\DRR\ViewRates.aspx.vb:911 System.Web.UI.WebControls.Button.OnClick(EventArgs e) +115 System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +140 System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +29 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2981 ________________________________________ Version Information: Microsoft .NET Framework Version:2.0.50727.8009; ASP.NET Version:2.0.50727.8010