Receiving "Unauthorized (401)" error in HttpWebRequest to SSRS 2008 - asp.net

I'm using HttpWebRequest to programatically export an SSRS 2008 report in PDF format. My problem however, is my NetworkCredentials don't seem to be working. I'm receiving an Unauthorized (401) error when trying access SSRS.
I know the NetworkCredentials I supplied are correct. If I log into our SSRS web service manually, these are the exact credentials I use. Also, this works fine locally, just not up on our server.
The report is run on our asp.net 4.0 website. When the user clicks the "Generate Report" button, the following code is executed (the error occurs on my 2nd line, on WebRequest.Create) to try to connect to my SSRS 2008:
string sTargetURL = "MY_REPORT_SERVER?/REPORT_NAME&rs:format=pdf&rs:command=render&rc:parameters=Collapsed";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sTargetURL);
req.PreAuthenticate = true;
req.Credentials = new NetworkCredential("Username", "Password", "Domain");
HttpWebResponse HttpWResp = (HttpWebResponse)req.GetResponse();
Stream fStream = HttpWResp.GetResponseStream();
byte[] fileBytes = ReadFully(fStream);
HttpWResp.Close();
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ContentType = "application/pdf";
System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=\"" + reportName + ".pdf"\"");
System.Web.HttpContext.Current.Response.BinaryWrite(fileBytes);
System.Web.HttpContext.Current.Response.Flush();
System.Web.HttpContext.Current.Response.End();

Outside the application, are you able to run the report locally and in the Report Manager/Server? If so, what type of data source does the report use? It could be that the data source does not accept the credentials double-hopping from the Report Server. You may need to create a domain account with the necessary read rights and configure the data source on the Report Server to impersonate these credentials.

Related

HttpWebRequest and Authentication

I am trying to use Forms Authenication with the httpwebrequest but I seem not to have any success. Here is what I am doing:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = WebRequestMethods.Http.Get;
// Authentication items -------------------------------------------
request.UseDefaultCredentials = false;
request.PreAuthenticate = true;
// Attempt to set username and password:
CredentialCache cc = new CredentialCache();
cc.Add(
new Uri(url),
"Basic",
new NetworkCredential("username", "validpassword", "domain")
);
request.Credentials = cc;
request.AllowAutoRedirect = true;
request.KeepAlive = true;
request.Timeout = 10000;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
// request html
response = (HttpWebResponse)request.GetResponse();
The problem is that even with a valid password and username for the domain this is always throwing an exception.
Can anyone help?
NOTES:
Exception Type: WebException
Exception Message: "The remote server returned an error: (401) Unauthorized."
Exception Status: Protocol
Error Exception Occurring at: response =(HttpWebResponse)request.GetResponse();
Exception Stack Trace: None
... sorry
I add Credentials for HttpWebRequest .
myReq.UseDefaultCredentials = true;
myReq.PreAuthenticate = true;
myReq.Credentials = CredentialCache.DefaultCredentials;
I’d like to know the sub status code of the 401 error you encountered. The 401 error contains the following sub status code:
401.1: Access is denied due to invalid credentials.
401.2: Access is denied due to server configuration favoring an alternate authentication method.
401.3: Access is denied due to an ACL set on the requested resource.
401.4: Authorization failed by a filter installed on the Web server.
401.5: Authorization failed by an ISAPI/CGI application.
401.7: Access denied by URL authorization policy on the Web server.
Because the project works well on your machine, I doubt it is a process identity issue. By default the application pool in IIS 6.0 uses “Network Service” as its identity. This account is restricted, so that you may encounter access deny issue.
For troubleshooting purpose, please try to change the application pool’s identity to “Local System”. If this method can resolve the issue, change back the identity to “Network Service”, and grant read/write permission to the xml file you want to read/write.
About how to change application pool’s identity, please refer to the following steps:
1. Open IIS manager (Start | Control Panel | Administrative Tools | Internet Information Services Manager).
2. Expand the “Application Pools” node.
3. Right click the application pool which your project is using, and then select “Properties”.
4. Click “Identity” tab.
5. Choose “Local System” in the Predefined dropdown list.
About how to grant permission to a file, please check these steps:
1. Open Windows Explorer.
2. Right click the file, and then select "Properties".
3. Click the "Security" tab.
4. Add "Network Service" in access list and check "Modify", "Read", and "Write" for it.
In addition, other files may cause this issue too, you can use Filemon to monitor any access file deny issues.
FileMon for Windows v7.04
http://www.microsoft.com/technet/sysinternals/FileAndDisk/Filemon.mspx

Reporting Services 2008 - 401: Unauthorized

I've an application that connects to Reporting Services in SQL Server 2008 R2.
The error is the following:
System.Net.WebException: The request failed with HTTP status 401: Unauthorized.
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse
(SoapClientMessage message, WebResponse response, Stream responseStream,
Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke
(String methodName, Object[] parameters)
at Microsoft.SqlServer.ReportingServices2005.Execution.ReportExecutionService.LoadReport
(String Report, String HistoryID)
The application is running in production fine in 2 different customers, so it's not a codeing issue.
I'm trying to install it now on a customer's server, which is using AD. The SQL Server and the IIS is all in the same machine though, so I don't really care about AD.
It runs if I run IE as Administrator, but it doesn't work with other users. The ASP.NET app is connecting to SSRS using a user created in the local machine (called ReportingServicesUser), member of the ReportingServicesUser group.
Things I've tried:
Adding ReportingServicesUser to the Site Settings in the RS website (did the same for Network Service, IUSR, the Authenticated Users group, Local Service, etc)
Adding ReportingServicesUser to the folder permissions in the RS website (did the same for Network Service, IUSR, the Authenticated Users group, Local Service, etc)
Added permissions for that users to the databases (app database and RS related dbs)
Added NTFS permissions to the RS folders (I will double check though).
Connecting to the RS using http://localhost, http://computername and http://domain.com
For reference, the code is this (simplified version):
var service = new ReportExecutionService();
service.Credentials = new NetworkCredential("ReportingServicesUser", "password");
service.Url = "http://computername:90/ReportServer/ReportExecution2005.asmx";
service.ExecutionHeaderValue = new ExecutionHeader();
var execInfo = new ExecutionInfo();
execInfo = service.LoadReport("path-to-the-report", null);
===> Here it throws the exception
I've read a lot of posts and pages about this but I cannot get an answer that works for me.
OK, I've finally had to change the code to:
rs.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
and it worked. Probably there's another solution but I couldn't find it out.
Are you sure you gave "ReportingServicesUser" browse permissions for the specific report in ssrs? The request never made it to the server it seems but I would check \Reporting Services\LogFiles just to be certain.
Also, Your "report user" user needs to be defined on the reporting server with the credentials you send.

Authentication Issue when accesing Reporting Service

Well, I already tried a lot of stuff to solve this issue, but none did.
I developed a Reporting Service (2005) and deployed it.
This report will be used by everyone who access a website (it's a internet site, so, won't be accessed by intranet) developed on the framework 3.5 (but I think the framework's version is not the source of the problem).
When the user clicks on the button to download the .pdf which the Reporting automatically generates (the end-user never sees the html version of the Report), it asks for windows credentials.
If the user enters a valid credential (and this credential must be a valid credential on the server which the Reporting Service is deployed), the .pdf is obviously downloaded.
But this can't happen. The end-user must download the .pdf directly, without asking for credentials. Afterall, he doesn't even have the credentials.
Response.Redirect("http://MyServer/ReportServer/Pages/ReportViewer.aspx?%2fReportLuiza%2fReportContract&rs:Format=PDF&NMB_CONTRACT=" + txtNmbContractReport.Text);
The code snippet above, shows the first version of my code when the user clicks the button. This one propmts for the Windows credentials.
I already tried to change on IIS the Authentication of the virtual directory ReportServer, but the only one which works is the Windows Credentials. The other ones doesn't even let me open the virtual directory of the Report or the Report Manager's virtual directory.
When I tried to change it to Anonymous Authentication he couldn't access the DataBase. Then I choose the option to Credentials stored securely on the report server. Still doesn't work.
The physical directory of my ReportServer virtual directory points to the reporting server folder on the Hard Disk (C:\Program Files\Microsoft SQL Server\MSSQL.5\Reporting Services\ReportServer). I moved the same folder to my wwwroot directory.
Didn't work. The virtual directory didn't even open. Then I read this could be a problem because I had the same name on two folders (one in C: and other in wwwroot). So I changed the name of the one in wwwroot. Same issue of the DataBase connection couldn't be done.
I returned the physical path to C:
Below, is the second version of my button's event code:
ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rs.Url = "http://MyServer/ReportServer/ReportExecution2005.asmx";
// Render arguments
byte[] result = null;
string reportPath = "/ReportLuiza/ReportContract";
string format = "PDF";
// Prepare report parameter.
ParameterValue[] parameters = new ParameterValue[1];
parameters[0] = new ParameterValue();
parameters[0].Name = "NMB_CONTRACT";
parameters[0].Value = txtNmbContractReport.Text;
string encoding;
string mimeType;
string extension;
Warning[] warnings = null;
string[] streamIDs = null;
ExecutionInfo execInfo = new ExecutionInfo();
ExecutionHeader execHeader = new ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
execInfo = rs.LoadReport(reportPath, null);
rs.SetExecutionParameters(parameters, "pt-br");
String SessionId = rs.ExecutionHeaderValue.ExecutionID;
try
{
result = rs.Render(format, null, out extension, out encoding, out mimeType, out warnings, out streamIDs);
execInfo = rs.GetExecutionInfo();
}
catch (SoapException se)
{
ShowMessage(se.Detail.OuterXml);
}
// Write the contents of the report to an pdf file.
try
{
using (FileStream stream = new FileStream(#"c:\report.pdf", FileMode.Create, FileAccess.ReadWrite))
{
stream.Write(result, 0, result.Length);
stream.Close();
}
}
catch (Exception ex)
{
ShowMessage(ex.Message);
}
For this code, I had to add a WebReference to the .asmx file mentioned in it.
When I'm debugging (on Visual Studio 2010), the code above works fine, doesn't asking for credentials (unfortunately, it doesn't prompt the option to open, save or cancel de file download. But this is another problem, no need to worry with it now) and save the file on C:.
When published, the code doesn't work. An erros says: The permission granted to user 'IIS APPPOOL\ASP.NET v4.0' are insuficient for performing this operation. So I added to the Reporting Service's users this user. When I tried again, the error is: Login failed for user IISAPPPOOL\ASP.NET v4.0. Cannot create a connection to data source 'MyDataSourceName'.
Both Report and WebSite are deployed/published on the same server with a IIS 7.5 version.
Summarizing: I need a solution where there is no credential prompt, and the user can choose where it wants to save the .pdf file.
Any help will be appreciated.
If you need more information to help me, just ask.
Thanks in advance.
One solution would be to create a new App Pool with an account that has the rights to access your restricted resources and then assign your web application to it.

How do you send an attachment with cdo.message if the file is in use

I am trying to send an email in classic asp site with an attachment. I am recieving the error "The process cannot access the file because it is being used by another process. "
The file is sitting in a shared folder on the same physical server that is hosting the site. If I check in computer management on the server I can confirm that a user has it open.
My question then is: Am I able to send a copy of the file that is saved to disk using cdo.message if that file is in use? I stripped away the rest of my code to do a test and I was still getting the same error using this.
'Create the Message Object
Set objMsg = Server.CreateObject("CDO.Message")
'Set the properties of the Message
With objMsg
Set .Configuration = cdoConfig
.From = sFrom
.To = sTo
.Subject = sSubject
.TextBody = sBody
.Send
End With
No you can't circumvent this restriction nor would you want to else you could be sending a corrupt file.

The attempt to connect to the report server failed. ssrs reporting

Hi, I am having problem while connecting to ssrs report. My report is running successfully on the server and i am attaching screen shot of the report also.
Client Code:
ReportViewer1.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Remote;
ReportViewer1.ServerReport.ReportServerUrl = new Uri("http://nysa31:8080/Reports_MS2008");
ReportViewer1.ServerReport.ReportPath = "~/New Item";
ReportParameter[] Params = new ReportParameter[1];
Params[0] = new ReportParameter("EmployeeID", "990");
ReportViewer1.ServerReport.SetParameters(Params);
ReportViewer1.ServerReport.Refresh();
I am getting this error. The attempt to connect to the report server failed. Check your connection information and that the report server is a compatible version.]
The Report Server URL you have set seems to be the Report Manager URL.
Enter the Report Server URL to resolve the issue.
You may want to have a bit of a read about accessing SSRS via windows auth, e.g.:
http://praveenbattula.blogspot.com/2010/01/report-viewer-control-authentication.html
use
http://Nysa31:8080/Reports_MS2008
instead of
http://nysa31:8080/Reports_MS2008
and folder names must starts with Uppercase letter.
because \n and \r are new line charectors. path name mayn't work .

Resources