问题
I have the following code which returns the reports from my SSRS server, afterwards I then store the paths to each individual list which allows users to run them from within the application. The below works fine.
NetworkCredential serviceCredentials = new NetworkCredential()
{
UserName = username,
SecurePassword = EncryptionManager.DecryptToSecureString(password),
Domain = domain
};
reports = new ObservableCollection<object>(reportsManager.FindReports(reportsWebService, reportsFolderName, serviceCredentials));
//FindReports
ReportingService2005 rs = new ReportingService2005();
rs.Url = reportsWebService;
rs.Credentials = serviceCredentials;
CatalogItem[] catalogItems = rs.ListChildren(@"/" + reportsFolderName, false);
However the problem is when a user selects a report to view it shows the following error:
The permissions granted to user are insufficient for performing this operation.
I understand that the quick fix to this would be to add the users domain into the security section on the Report server, however this is not appropriate.
My question is I can supply credentials to allows a specified user to access the report folder is it possible to pass this along so that user can run a report?
Each of my reports use built in connection strings NOT windows authentication.
Edit: I am using Reporting WinForms.
回答1:
Windows Forms
In a windows forms project you can pass a suitable System.Net.NetworkCredential to ServerReport.ReportServerCredentials.NetworkCredentials property of ReportViewer
. This way, all reports will be executed using the passed credential:
reportViewer1.ServerReport.ReportServerCredentials.NetworkCredentials =
new System.Net.NetworkCredential("username", "password", "domain");
Web Forms
The solution for a Web Forms is different. In a Web Forms project, to pass a suitable credential to RePortViewer
you need to implement IReportServerCredentials. Then you can assign the value to ServerReport.ReportServerCredentials property of ReportViewer
control. This way, all reports will be executed using the passed credential.
Example
Here is a simple implementation. It's better to store username, password and domain name in app config and read them from config file:
using System;
using System.Net;
using System.Security.Principal;
using Microsoft.Reporting.WebForms;
[Serializable]
public sealed class MyReportServerCredentials : IReportServerCredentials
{
public WindowsIdentity ImpersonationUser { get { return null; } }
public ICredentials NetworkCredentials
{
get
{
return new NetworkCredential("username", "password", "domain");
}
}
public bool GetFormsCredentials(out Cookie authCookie, out string userName,
out string password, out string authority)
{
authCookie = null;
userName = password = authority = null;
return false;
}
}
Then in Page_Load
pass the credential this way:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
this.ReportViewer1.ServerReport.ReportServerCredentials =
new Sample.MyReportServerCredentials();
}
Note
In cases which you want to use ReportViewer
with no session state you can also implement IReportServerConnection. In this case you need to add a key value in appsettings
section of config file to introduce the implementation this way:
<add key="ReportViewerServerConnection" value="YourNameSpace.YourClass, YourAssemply" />
In this case, you don't need code in Page_Load
and the config would be enough. For more information take a look at this great blog post by Brian Hartman.
来源:https://stackoverflow.com/questions/40682877/running-all-ssrs-reports-through-one-report-user-ignoring-own-users-domain