I will post this as an answer instead of a comment. In working with Microsoft Support, I modified my code somewhat. I added a class that implemented IReportServerCredentials that returned a NetworkCredential with the user name and password. We still persisted in getting the 401 error. We started running network traces and noticed that the credentials were not showing up in the trace as we expected. We did see, however, NTLM negation taking place and failing.
We verified the rsReportServer.config had basic authentication enabled and disabled NTLM and Kerberos authentication just to be safe. Still failed with a 401.
After several back and forths with MS and many Bingle searches, we discovered that the .ServerReport.SetParameters method makes a call to the SSRS server. We were setting our .ServerReport.ReportServerCredentials after this. Simply moving the .ServerReport.ReportServerCredentials before the .ServerReport.SetParameters method solved the issue. The updated code is below.)
So, this was a programming error and not a configuration error. This will affect any SSRS instance that is not in the same domain as the website calling the ReportViewer control.
Imports Microsoft.Reporting.WebForms
Imports System.Net
Imports System.Security.Principal
Public Class ucReportPreview
Inherits System.Web.UI.UserControl
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
'gets the report viewer control from the session if it exists
If Not Session("Current_ReportFileName") Is Nothing Then
Dim sysOpt As New SystemOption
'Dim ReportServer As String = sysOpt.LookupValueByShortDescription("ReportServer")
'Dim ReportPath As String = sysOpt.LookupValueByShortDescription("ReportPath")
'Dim ReportFileName As String = Session("Current_ReportFileName").ToString
Dim ReportServer As String = "http://logsdon-ssrs/ReportServer"
'Dim ReportPath As String = "/InfoRail V5/IR-20141118"
Dim ReportPath As String = "/userinfo"
Dim ReportFileName As String = "Certification Requirements Due (By Employee)"
Dim myCreds As IReportServerCredentials = New MyReportServerCredentials("<userName>", "<password>", "<machine-or-domainName>")
If Not Session("Current_ReportParams") Is Nothing Then
Dim storedParams As Microsoft.Reporting.WebForms.ReportParameterCollection = CType(Session("Current_ReportParams"), Microsoft.Reporting.WebForms.ReportParameterCollection)
With ReportViewer1
.Reset()
.ServerReport.ReportServerCredentials = myCreds
.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Remote
.ServerReport.ReportServerUrl = New Uri(ReportServer) 'Report Server URL
.ServerReport.ReportPath = String.Format("{0}/{1}", ReportPath, ReportFileName) 'Report Name
.ServerReport.SetParameters(storedParams)
.ShowParameterPrompts = False
.SizeToReportContent = True
.ServerReport.Refresh()
End With
Else
Dim storedParams As Microsoft.Reporting.WebForms.ReportParameterCollection = CType(Session("Current_ReportParams"), Microsoft.Reporting.WebForms.ReportParameterCollection)
With ReportViewer1
.Reset()
.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Remote
.ServerReport.ReportServerUrl = New Uri(ReportServer) 'Report Server URL
.ServerReport.ReportPath = String.Format("{0}/{1}", ReportPath, ReportFileName) 'Report Name
.ServerReport.ReportServerCredentials = myCreds
.ShowParameterPrompts = True
.SizeToReportContent = True
.ServerReport.Refresh()
End With
End If
End If
End If
End Sub
Private Sub Page_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
'destroys the report viewer control in the session
Session("Current_ReportParams") = Nothing
End Sub
Protected Function GetReportName(Reportid As Integer) As String
Dim retval As String = String.Empty
'Dim rt As New ReportTableBLL(System.Web.HttpContext.Current.Session("ConnectionString"))
'retval = rt.GetReportfilenameByReportid(Reportid)
Return retval
End Function
End Class
Public NotInheritable Class MyReportServerCredentials
Implements IReportServerCredentials
Private _userName As String
Private _password As String
Private _domainName As String
Public ReadOnly Property ImpersonationUser() As WindowsIdentity Implements IReportServerCredentials.ImpersonationUser
Get
Return Nothing
End Get
End Property
Public ReadOnly Property NetworkCredentials() As ICredentials Implements IReportServerCredentials.NetworkCredentials
Get
Return New NetworkCredential(_userName, _password, _domainName)
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
Return False
End Function
Public Sub New(userName As String, password As String, domainName As String)
_userName = userName
_password = password
_domainName = domainName
End Sub
End Class