Showing posts with label implement. Show all posts
Showing posts with label implement. Show all posts

Monday, March 26, 2012

RSClientPrint and web-service rendering

I'm using the web-service to render the report with Reporting Services 2000, and I wish to implement client-side printing that will duplicate the functionality you'd ordinarily have using the Report Server.

The main motivation of rendering via the web-service is I can implement security on a per-request basis and completely hide the existence of the report server by doing everything server-side.

Unfortunately I have two problems with the RSClientPrint tool. Firstly, I can't USE it - whether this is a script problem or I don't have it installed properly I don't know. For reference, I have the .CAB file in the same folder and this is the tag I'm using to reference it in my HTML:

<OBJECT ID="RSClientPrint" CLASSID="CLSID:FA91DF8D-53AB-455D-AB20-F2F023E498D3" CODEBASE="RSClientPrint.cab" VIEWASTEXT></OBJECT>

And to print I'm using this JavaScript to set properties and call methods, I'd use syntax ie:

RSClientPrint.MarginLeft = 12.7;

However this results in a JavaScript error saying RSClientPrint is undefined. What else do I need to do?

Second concern: will the RSClientPrint require a resolvable, public URL path to the Report Server as parameters for the Print() function? ie the whole reason for using web-services was to hide the report server ...but the print parameters of the RSClientPrint seem to require parameters that're dispatched to the Report Server. I do not want the Report Server publically accessible at all costs. Is this not possible with RSClientPrint?

Hi Philip,

I have the same question with you.

Currently I'm using the IE's printing.

Another way is to render the report as PDF format and using PDF's printing function.

Best regards,

David

RSClientPrint and web-service rendering

I'm using the web-service to render the report with Reporting Services 2000, and I wish to implement client-side printing that will duplicate the functionality you'd ordinarily have using the Report Server.

The main motivation of rendering via the web-service is I can implement security on a per-request basis and completely hide the existence of the report server by doing everything server-side.

Unfortunately I have two problems with the RSClientPrint tool. Firstly, I can't USE it - whether this is a script problem or I don't have it installed properly I don't know. For reference, I have the .CAB file in the same folder and this is the tag I'm using to reference it in my HTML:

<OBJECT ID="RSClientPrint" CLASSID="CLSID:FA91DF8D-53AB-455D-AB20-F2F023E498D3" CODEBASE="RSClientPrint.cab" VIEWASTEXT></OBJECT>

And to print I'm using this JavaScript to set properties and call methods, I'd use syntax ie:

RSClientPrint.MarginLeft = 12.7;

However this results in a JavaScript error saying RSClientPrint is undefined. What else do I need to do?

Second concern: will the RSClientPrint require a resolvable, public URL path to the Report Server as parameters for the Print() function? ie the whole reason for using web-services was to hide the report server ...but the print parameters of the RSClientPrint seem to require parameters that're dispatched to the Report Server. I do not want the Report Server publically accessible at all costs. Is this not possible with RSClientPrint?

Hi Philip,

I have the same question with you.

Currently I'm using the IE's printing.

Another way is to render the report as PDF format and using PDF's printing function.

Best regards,

David

Friday, March 23, 2012

RS2005: ReportManager and Forms Authentication : The report server is not responding

Hi,

Sorry for the long post but I'll try to give a maximum of information.

I've tried to implement Form Authentication for Reporting Services. Right now, just about everything works as I would hope for, i.e.:

When I try to access http://<server>/ReportServer$SQLSERVER_2005, I am redirected to the authentication form.

When successfully authenticated, I can access the report

I can display reports throught the ReportViewer Web control by passing the authentication cookie.

Etc.

(Note: My implementation of Form Authentication was inspired by http://www.devx.com/dotnet/Article/26759/0/page/1 which seems similar to Microsoft Sample)

(The $SQLSERVER_2005 suffix is because SQL Server 2000 is also installed on the server, but I don't think Reporting Services 2000 is installed)

There is one thing which does not work however and it is the Report Manager.

When I try to access http://<server>/Reports$SQLSERVER_2005, I would expect to be redirected to the /Pages/UILogon.aspx page. Instead, I get an error page with the following message:

"The report server is not responding. Verify that the report server is running and can be accessed from this computer."

Both ReportServer and Reports are on the same server, both have the same security on the folder and in IIS (6.0), both have Anonymous security access "checked".

If I revert to the old .config files (prior to my modifications for Form Authentication) and remove Anonymous from IIS for both sites, everything works fine (like it did after the installation).

Here are excerpts from the config files I've modified in ReportManager:

RSWebApplication.config:

<UI>
<CustomAuthenticationUI>
<loginUrl>/Pages/UILogon.aspx</loginUrl>
<UseSSL>False</UseSSL>
</CustomAuthenticationUI>
<ReportServerUrl>http://<servername>/ReportServer$SQLSERVER_2005</ReportServerUrl>
</UI>

rsmgrpolicy.config:

<CodeGroup
class="FirstMatchCodeGroup"
version="1"
PermissionSetName="FullTrust"
Description="This code group grants MyComputer code Execution permission. ">
<IMembershipCondition
class="ZoneMembershipCondition"
version="1"
Zone="MyComputer" />

Web.config:

<identity impersonate="false" />

Here is the content of the log ReportServerWebApp_*.log (see error in bold):

<Header>
<Product>Microsoft SQL Server Reporting Services Version 9.00.1399.00</Product>
<Locale>en-US</Locale>
<TimeZone>Eastern Standard Time</TimeZone>
<Path>C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\LogFiles\ReportServerWebApp__11_10_2006_08_32_34.log</Path>
<SystemName>MSCAPP02</SystemName>
<OSName>Microsoft Windows NT 5.2.3790 Service Pack 1</OSName>
<OSVersion>5.2.3790.65536</OSVersion>
</Header>
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing MaxActiveReqForOneUser to '20' requests(s) as specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing MaxScheduleWait to default value of '1' second(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing DatabaseQueryTimeout to default value of '30' second(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing ProcessRecycleOptions to default value of '0' because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing RunningRequestsScavengerCycle to default value of '30' second(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing RunningRequestsDbCycle to default value of '30' second(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing RunningRequestsAge to default value of '30' second(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing CleanupCycleMinutes to default value of '10' minute(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing DailyCleanupMinuteOfDay to default value of '120' minutes since midnight because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing WatsonFlags to default value of '1064' because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing WatsonDumpOnExceptions to default value of 'Microsoft.ReportingServices.Diagnostics.Utilities.InternalCatalogException,Microsoft.ReportingServices.Modeling.InternalModelingException' because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing WatsonDumpExcludeIfContainsExceptions to default value of 'System.Data.SqlClient.SqlException,System.Threading.ThreadAbortException' because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing SecureConnectionLevel to default value of '1' because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing DisplayErrorLink to 'True' as specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing WebServiceUseFileShareStorage to default value of 'False' because it was not specified in Configuration file.
w3wp!ui!5!11/10/2006-08:32:39:: e ERROR: The report server is not responding. Verify that the report server is running and can be accessed from this computer.
w3wp!ui!5!11/10/2006-08:32:39:: e ERROR: HTTP status code --> 500
-Details--
Microsoft.ReportingServices.UI.Global+RSWebServiceWrapper+CantCommunicateWithReportServerException: The report server is not responding. Verify that the report server is running and can be accessed from this computer.

at Microsoft.ReportingServices.UI.Global.RSWebServiceWrapper.GetSecureMethods()

at Microsoft.SqlServer.ReportingServices2005.RSConnection.IsSecureMethod(String methodname)

at Microsoft.SqlServer.ReportingServices2005.RSConnection.ValidateConnection()

at Microsoft.ReportingServices.UI.ReportingPage.EnsureHttpsLevel(HttpsLevel level)

at Microsoft.ReportingServices.UI.ReportingPage.ReportingPage_Init(Object sender, EventArgs args)

at System.EventHandler.Invoke(Object sender, EventArgs e)

at System.Web.UI.Control.OnInit(EventArgs e)

at System.Web.UI.Page.OnInit(EventArgs e)

at System.Web.UI.Control.InitRecursive(Control namingContainer)

at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
w3wp!ui!5!11/10/2006-08:32:40:: e ERROR: Exception in ShowErrorPage: System.Threading.ThreadAbortException: Thread was being aborted.
at System.Threading.Thread.AbortInternal()
at System.Threading.Thread.Abort(Object stateInfo)
at System.Web.HttpResponse.End()
at System.Web.HttpServerUtility.Transfer(String path, Boolean preserveForm)
at Microsoft.ReportingServices.UI.ReportingPage.ShowErrorPage(String errMsg) at at System.Threading.Thread.AbortInternal()
at System.Threading.Thread.Abort(Object stateInfo)
at System.Web.HttpResponse.End()
at System.Web.HttpServerUtility.Transfer(String path, Boolean preserveForm)
at Microsoft.ReportingServices.UI.ReportingPage.ShowErrorPage(String errMsg)

So that's it. Thanks for any help you can provide.

Nicolas

So? Anyone can assist me? Is this the right place to post an issue like this. I've searched a lot on the Web and I've yet to find a solution. The error message doesn't help me much either (As far as I can see, the report server is running since I can display the reports).|||

Here is something you can start with for investigation:

1. Check reportserver log file to see whether there is any error there.

2. Check IIS logging to make sure the request does get to report server (some times you need to iisreset to flush the most recent result).

3. You can use some tcp tracing tool to check the traffic between report manager and report server to check if anything wrong.

|||

Hi Yalei,

First, thanks for you help.

1. Check reportserver log file to see whether there is any error there:

Assuming you are refering to one of the "\Reporting Services\LogFiles\reportserver_*.log", i don't see anything wrong there. No "ERRORS", only "INFO". An entry such as the following:

"w3wp!library!5!11/14/2006-14:44:08:: i INFO: Cleaned 0 batch records, 0 policies, 0 sessions, 0 cache entries, 0 snapshots, 0 chunks, 0 running jobs, 0 persisted streams"

appears every 10 minutes. The log doesn't seem to react when I access http://<servername>/Reports$SQLSERVER_2005.

2. Check IIS logging to make sure the request does get to report server (some times you need to iisreset to flush the most recent result).

Below is a sample of my IIS Logging. I don't know if you can see something in it? Something that strikes me as strange is the time (the request is done circa 15:10 and the displayed hour is 20:17). The server time seems alright (i.e. circa 15:10) so I don't know where the logging gets its timestamp... Could this be the source of the problem?

Note: XXX.XXX.XXX.XXX is the server IP and YYY.YYY.YYY.YYY is the client IP.

#Date: 2006-11-14 20:17:04
#Fields: date time s-sitename s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status
2006-11-14 20:17:04 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005 - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 301 0 0
2006-11-14 20:17:21 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/Home.aspx - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 302 0 0
2006-11-14 20:17:26 W3SVC1 XXX.XXX.XXX.XXX POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - XXX.XXX.XXX.XXX - 302 0 0
2006-11-14 20:17:26 W3SVC1 XXX.XXX.XXX.XXX GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - XXX.XXX.XXX.XXX - 200 0 0
2006-11-14 20:17:28 W3SVC1 XXX.XXX.XXX.XXX POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - XXX.XXX.XXX.XXX - 302 0 0
2006-11-14 20:17:28 W3SVC1 XXX.XXX.XXX.XXX GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - XXX.XXX.XXX.XXX - 200 0 0
2006-11-14 20:17:29 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/Pages/Folder.aspx - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 500 0 0

2006-11-14 20:20:55 W3SVC1 XXX.XXX.XXX.XXX POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - XXX.XXX.XXX.XXX - 302 0 0
2006-11-14 20:20:55 W3SVC1 XXX.XXX.XXX.XXX GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - XXX.XXX.XXX.XXX - 200 0 0
2006-11-14 20:20:55 W3SVC1 XXX.XXX.XXX.XXX POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - XXX.XXX.XXX.XXX - 302 0 0
2006-11-14 20:20:55 W3SVC1 XXX.XXX.XXX.XXX GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - XXX.XXX.XXX.XXX - 200 0 0
2006-11-14 20:20:57 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/Pages/Folder.aspx - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 500 0 0
2006-11-14 20:20:57 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/js/ReportingServices.js - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 200 0 64
2006-11-14 20:20:57 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/styles/ReportingServices.css - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 200 0 64
2006-11-14 20:20:57 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/images/blank.gif - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 200 0 64
2006-11-14 20:20:57 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/images/48error.jpg - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 200 0 64

3. You can use some tcp tracing tool to check the traffic between report manager and report server to check if anything wrong.

Could this really cause problems? Like I've said, both report server and report manager are on the same machine. Also, when I use the "original" ".config" for Report Server and Report Manager, everything works OK. Do you still think it would be wortwhile to use TCP tracing tools? If so, can you recommend one (never used those...)?

Thanks again

|||

The following is suspicious. It happens again and again in the log. It is the redirection at Report Server. It should not happen when you perform login from report manager. This means from you cutomized UI login page at report manager, the forms auth cookie does not get passed in. You need to check that you called LogonUser soap API, retrieved the forms auth cookie and passed in the following request to report server.

2006-11-14 20:17:26 W3SVC1 XXX.XXX.XXX.XXX POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - XXX.XXX.XXX.XXX - 302 0 0
2006-11-14 20:17:26 W3SVC1 XXX.XXX.XXX.XXX GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - XXX.XXX.XXX.XXX - 200 0 0

|||

Thanks again for your support.

I do call LogonUser in my UILogon.aspx page (as well as my /MyWorkspace/Login.aspx page used for Report Server and my application). One thing I find weird is that when I access http://MSCAPP02/Reports$SQLSERVER_2005/, I am not redirected to the UILogon.aspx page. However, I can access the UILogon page directly and the page seems to work well by itself. Don't know why I keep getting redirected to Login.aspx. Here's the IIS Log when I log through the UILogon.aspx page:

2006-11-15 17:17:13 W3SVC1 172.17.70.73 GET /Reports$SQLSERVER_2005/Pages/UILogon.aspx - 80 - 142.101.228.177 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 200 0 0
2006-11-15 17:17:35 W3SVC1 172.17.70.73 POST /ReportServer$SQLSERVER_2005/ReportService.asmx - 80 - 172.17.70.73 - 200 0 0
2006-11-15 17:17:35 W3SVC1 172.17.70.73 POST /Reports$SQLSERVER_2005/Pages/UILogon.aspx - 80 - 142.101.228.177 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 302 0 0
2006-11-15 17:17:35 W3SVC1 172.17.70.73 POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - 172.17.70.73 - 302 0 0
2006-11-15 17:17:35 W3SVC1 172.17.70.73 GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - 172.17.70.73 - 200 0 0
2006-11-15 17:17:36 W3SVC1 172.17.70.73 POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - 172.17.70.73 - 302 0 0
2006-11-15 17:17:36 W3SVC1 172.17.70.73 GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - 172.17.70.73 - 200 0 0
2006-11-15 17:17:37 W3SVC1 172.17.70.73 GET /Reports$SQLSERVER_2005/Pages/Folder.aspx - 80 - 142.101.228.177 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 500 0 0

As I've said earlier, my code is mostly taken from an online tutorial. The code for the UILogon.aspx page is similar to that of my Login.aspx page. There does seem to be a good quantity of code to pass the auth cookie around (can't say I understand why all of this code does). In case you want to take a peek, here it is:

The code for the authentication in UILogon:

private void BtnLogon_Click(object sender, System.EventArgs e)
{
bool passwordVerified = false;
string sMsg = "";
string sUrl = "";

try
{
ReportServerProxy server = new ReportServerProxy();
server.Url = AuthenticationUtilities.GetWebServiceUrl();
server.LogonUser(TxtUser.Text, TxtPwd.Text, null);
passwordVerified = true;
}
catch (Exception ex)
{
return;
}
if (passwordVerified == true)
{
lblMessage.Text = "Logon successful: User is authenticated";
string redirectUrl = Request.QueryString["ReturnUrl"];
if (redirectUrl != null) HttpContext.Current.Response.Redirect(redirectUrl, false);
else HttpContext.Current.Response.Redirect("./Folder.aspx", false);
}
else
{
lblMessage.Text = "Invalid username or password";
}
}

... And the code for the ReportServerProxy which takes care of the cookie...

public class ReportServerProxy : ReportingService
{
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request;
request = (HttpWebRequest)HttpWebRequest.Create(uri);

// Create a cookie jar to hold the request cookie
CookieContainer cookieJar = new CookieContainer();
request.CookieContainer = cookieJar;
Cookie authCookie = AuthCookie;

// if the client already has an auth cookie
// place it in the request's cookie container
if (authCookie != null) request.CookieContainer.Add(authCookie);

request.Timeout = -1;
request.Headers.Add("Accept-Language", HttpContext.Current.Request.Headers["Accept-Language"]);
return request;
}

protected override WebResponse GetWebResponse(WebRequest request)
{
WebResponse response = base.GetWebResponse(request);
string cookieName = response.Headers["RSAuthenticationHeader"];

// If the response contains an auth header, store the cookie
if (cookieName != null)
{
Utilities.CustomAuthCookieName = cookieName;
HttpWebResponse webResponse = (HttpWebResponse)response;
Cookie authCookie = webResponse.Cookies[cookieName];

// If the auth cookie is null, throw an exception
if (authCookie == null)
{
throw new Exception("Authorization ticket not received by LogonUser");
}

// otherwise save it for this request
AuthCookie = authCookie;

// and send it to the client
Utilities.RelayCookieToClient(authCookie);
}
return response;
}

private Cookie AuthCookie
{
get
{
if (m_Authcookie == null)
m_Authcookie = Utilities.TranslateCookie(
HttpContext.Current.Request.Cookies[Utilities.CustomAuthCookieName]);
return m_Authcookie;
}
set
{
m_Authcookie = value;
}
}
private Cookie m_Authcookie = null;
}

... And the code for the Utilities class...

internal sealed class Utilities
{
internal static string CustomAuthCookieName
{
get
{
lock (m_cookieNamelockRoot)
{
return m_cookieName;
}
}
set
{
lock (m_cookieNamelockRoot)
{
m_cookieName = value;
}
}
}

private static string m_cookieName;
private static object m_cookieNamelockRoot = new object();

private static HttpCookie TranslateCookie(Cookie netCookie)
{
if (netCookie == null) return null;

HttpCookie webCookie = new HttpCookie(netCookie.Name, netCookie.Value);

// Add domain only if it is dotted - IE doesn't send back the cookie
// if we set the domain otherwise
if (netCookie.Domain.IndexOf('.') != -1)
webCookie.Domain = netCookie.Domain;

webCookie.Expires = netCookie.Expires;
webCookie.Path = netCookie.Path;
webCookie.Secure = netCookie.Secure;
return webCookie;
}

internal static Cookie TranslateCookie(HttpCookie webCookie)
{
if (webCookie == null) return null;
Cookie netCookie = new Cookie(webCookie.Name, webCookie.Value);

if (webCookie.Domain == null)
netCookie.Domain = HttpContext.Current.Request.ServerVariables["SERVER_NAME"];

netCookie.Expires = webCookie.Expires;
netCookie.Path = webCookie.Path;
netCookie.Secure = webCookie.Secure;
return netCookie;
}

internal static void RelayCookieToClient(Cookie cookie)
{
// add the cookie if not already in there
if (HttpContext.Current.Response.Cookies[cookie.Name] == null)
{
HttpContext.Current.Response.Cookies.Remove(cookie.Name);
}
HttpContext.Current.Response.SetCookie(TranslateCookie(cookie));
}
}

Sorry for the long post with lots of code. I'm not used to posting in forums so I'm not sure what is the best way to do this.

Like I said, this is basically the same code used by the Login.aspx page and it seems to work great there, so I guess it should be alright.

One thing I find kind of strange is the following in the Report Manger web.config:

<system.web>
[...]
<authentication mode="Windows" />
<identity impersonate="false" />
[...]
</system.web>

The step by step guide didn't ask to change it but should'nt this be mode="Forms"?

Thanks again, your support is really appreciated.

|||

Have you tried using hardcoding the url using \\localhost\ instead of machine IP in place of GetWebServiceURL().

string sUrl = "";
try
{
ReportServerProxy server = new ReportServerProxy();
server.Url = /ReportService2005.asmx" href="http://links.10026.com/?link=http://localhost/_3CREPORTSERVER_3E/ReportService2005.asmx">http://localhost/<REPORTSERVER>/ReportService2005.asmx;
server.LogonUser(TxtUser.Text, TxtPwd.Text, null);
passwordVerified = true;
}
catch (Exception ex)
{
return;
}

|||

Hi Ross, thanks for your input.

Previously (a few days ago) GetWebServiceURL() was reading the url in a config file. But since I had problems with that, I modified GetWebServiceURL() to return a hardcoded string. Mine was http://<servername>/<reportserver>/ReportService.asmx instead of your http://localhost/<REPORTSERVER>/ReportService2005.asmx. So I decided to try yours but if anything, it is worse, i.e. when I authenticate from UILogon.aspx with my string, I get redirected to the error page:

"The report server is not responding. Verify that the report server is running and can be accessed from this computer"

When I use your string, I get the following exception:

System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: http://schemas.microsoft.com/sqlserver/2003/12/reporting/reportingservices/LogonUser. at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest() at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message) at System.Web.Services.Protocols.SoapServerProtocol.Initialize() at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

However, in both cases, if I try to access http://<servername>/Reports$SQLSERVER_2005/, I get the error page...

"The report server is not responding. Verify that the report server is running and can be accessed from this computer"

...instead of being redirected to the UILogon.aspx page (which I find puzzling).

Also, what's the difference between ReportService.asmx and ReportService2005.asmx? I sometimes wonder if this may be the source of my problems. Everywhere in my code, I was using ReportService.asmx.

Thanks

|||

Well it sounds like the web server is listening. However you may be passing a parameter in the HTTP request that does not match what the server is expecting.

I would double check to make sure the interface you are implementing is the one you are targeting.

using Microsoft.SqlServer.ReportingServices.ReportService2005;

....

public class ReportServerProxy : RS.ReportExecutionService

Where RS is a reference to /ReportServer/reportExecution2005.asmx" href="http://links.10026.com/?link=http://_3Crsserver_3E/ReportServer/reportExecution2005.asmx">http://<RSSERVER>/ReportServer/reportExecution2005.asmx

|||

Hi again Ross.

I've seen the following post: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=119960&SiteID=1 which answers the ReportService.asmx vs ReportService2005.asmx question. If I undrestand the answer correctly, I should be able to use ReportService.asmx, with a reduced feature set. Perhaps this reduced feature set means I can't use the 2005 version of Report Manager...

If you look at the code I posted, you'll see that I wasn't refering to ReportService2005 (in ReportService2005.asmx) but ReportService (in ReportService.asmx). Also, my proxy wasn't extending you RS.ReportExecutionService but the ReportingService class. So the exception is expected, in a way.

I'll try to rework my implementation using ReportService2005.asmx to see if I have any more luck and I'll let you know. I hope I don't have to change too many things as most of the code wasn't written by me, it was taken from a tutorial online.

|||

Hi Nicolas,

I'm a little bit past the issue you're having. I struggled with it a long......... time. As long as I run Report Server and Report Manager on the same machine things are fine with my custom security extension. The key in my case was to use the full machine.domain.com name everywhere. By everywhere I mean in both web.config files, the RSWebApplication.config file for ReportManager and the RSReportServer.config file on report server. Finally, in your browser always refrence the report manager url with the full machine.domain.com url never just 'machine' and certainly not with just localhost. I don't have the instance names as part of my VDirs but otherwise things are setup pretty similar to yours.

The problem I'm currently having is I'm trying to run ReportManager on a different box than ReportServer I get the exact same exception messages that you're seeing.

If anyone can verify that its possible to run ReportManager and ReportServer on different machines with a custom security extension I'd love to hear about it. I've also got a support call open with Microsoft and we're working the issue. I'll let the forum know how it turns out.....

cheers
Perry

|||

Hi Perry,

Thanks for your input.

In my case, I don't have a "machine.domain.com" (or if I do, i don't know what it is). This is a developpement server in an intranet. However, I do use the servername "everywhere" (i.e. in the config files and in the way I type my url in my browser). I think the key is just to be consistent in how you address it. Otherwise, I guess I could type in the IP address everywhere.

When you say your setup is similar to mine, do you mean my current setup (using "ReportService.asmx") or the one I was about to convert to (using "ReportService2005.asmx)?

As for running the services from different servers, have you seen the post below? You may find some clues in there...

http://groups.google.ca/group/microsoft.public.sqlserver.reportingsvcs/browse_frm/thread/991c9178ceab8f58/8f1a447aa60ad837?lnk=st&q=reporting+services+the+server+is+not+responding&rnum=3&hl=en#8f1a447aa60ad837

Thanks again

|||

Nicolas,

Did you ever work past your issue? I'm having an issue with a custom security extension that is a little different but related to cookies being passed from Report Manager to Reporting Services and I found your post. I'm curious if your problem was solved and if the solution would help me in any way.

Thanks,

Kyle

|||

Hi Kyle,

I haven't spent more time on the issue since my last post as other matters required my attention. However, I do plan to revisit the issue in the near future. If I do manage to make it work, I'll post here. If you have any solution hints on your side, these would be appreciated as well.

Cheers,

Nicolas

|||

Hey Nicolas,

I'm not 100% working but finally did find the major hang up I was having. Turns out it's a bug in how cookies are passed by controls in Report Manager. Namely when trying to view a report the custom authentication cookie is not passed to the Report Server.

Check this KB article just in case you're getting this error. The patch was free to get from support and it should be in the next service pack. If you get back to this and you're still stuck let me know. I know more about custom extensions then I ever planned on knowing at this point. :)

Happy Coding!

Kyle

www.kylefinley.net

RS2005: ReportManager and Forms Authentication : The report server is not responding

Hi,

Sorry for the long post but I'll try to give a maximum of information.

I've tried to implement Form Authentication for Reporting Services. Right now, just about everything works as I would hope for, i.e.:

When I try to access http://<server>/ReportServer$SQLSERVER_2005, I am redirected to the authentication form. When successfully authenticated, I can access the report I can display reports throught the ReportViewer Web control by passing the authentication cookie. Etc.

(Note: My implementation of Form Authentication was inspired by http://www.devx.com/dotnet/Article/26759/0/page/1 which seems similar to Microsoft Sample)

(The $SQLSERVER_2005 suffix is because SQL Server 2000 is also installed on the server, but I don't think Reporting Services 2000 is installed)

There is one thing which does not work however and it is the Report Manager.

When I try to access http://<server>/Reports$SQLSERVER_2005, I would expect to be redirected to the /Pages/UILogon.aspx page. Instead, I get an error page with the following message:

"The report server is not responding. Verify that the report server is running and can be accessed from this computer."

Both ReportServer and Reports are on the same server, both have the same security on the folder and in IIS (6.0), both have Anonymous security access "checked".

If I revert to the old .config files (prior to my modifications for Form Authentication) and remove Anonymous from IIS for both sites, everything works fine (like it did after the installation).

Here are excerpts from the config files I've modified in ReportManager:

RSWebApplication.config:

<UI>
<CustomAuthenticationUI>
<loginUrl>/Pages/UILogon.aspx</loginUrl>
<UseSSL>False</UseSSL>
</CustomAuthenticationUI>
<ReportServerUrl>http://<servername>/ReportServer$SQLSERVER_2005</ReportServerUrl>
</UI>

rsmgrpolicy.config:

<CodeGroup
class="FirstMatchCodeGroup"
version="1"
PermissionSetName="FullTrust"
Description="This code group grants MyComputer code Execution permission. ">
<IMembershipCondition
class="ZoneMembershipCondition"
version="1"
Zone="MyComputer" />

Web.config:

<identity impersonate="false" />

Here is the content of the log ReportServerWebApp_*.log (see error in bold):

<Header>
<Product>Microsoft SQL Server Reporting Services Version 9.00.1399.00</Product>
<Locale>en-US</Locale>
<TimeZone>Eastern Standard Time</TimeZone>
<Path>C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\LogFiles\ReportServerWebApp__11_10_2006_08_32_34.log</Path>
<SystemName>MSCAPP02</SystemName>
<OSName>Microsoft Windows NT 5.2.3790 Service Pack 1</OSName>
<OSVersion>5.2.3790.65536</OSVersion>
</Header>
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing MaxActiveReqForOneUser to '20' requests(s) as specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing MaxScheduleWait to default value of '1' second(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing DatabaseQueryTimeout to default value of '30' second(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing ProcessRecycleOptions to default value of '0' because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing RunningRequestsScavengerCycle to default value of '30' second(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing RunningRequestsDbCycle to default value of '30' second(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing RunningRequestsAge to default value of '30' second(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing CleanupCycleMinutes to default value of '10' minute(s) because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing DailyCleanupMinuteOfDay to default value of '120' minutes since midnight because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing WatsonFlags to default value of '1064' because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing WatsonDumpOnExceptions to default value of 'Microsoft.ReportingServices.Diagnostics.Utilities.InternalCatalogException,Microsoft.ReportingServices.Modeling.InternalModelingException' because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing WatsonDumpExcludeIfContainsExceptions to default value of 'System.Data.SqlClient.SqlException,System.Threading.ThreadAbortException' because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing SecureConnectionLevel to default value of '1' because it was not specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing DisplayErrorLink to 'True' as specified in Configuration file.
w3wp!library!5!11/10/2006-08:32:35:: i INFO: Initializing WebServiceUseFileShareStorage to default value of 'False' because it was not specified in Configuration file.
w3wp!ui!5!11/10/2006-08:32:39:: e ERROR: The report server is not responding. Verify that the report server is running and can be accessed from this computer.
w3wp!ui!5!11/10/2006-08:32:39:: e ERROR: HTTP status code --> 500
-Details--
Microsoft.ReportingServices.UI.Global+RSWebServiceWrapper+CantCommunicateWithReportServerException: The report server is not responding. Verify that the report server is running and can be accessed from this computer.

at Microsoft.ReportingServices.UI.Global.RSWebServiceWrapper.GetSecureMethods()

at Microsoft.SqlServer.ReportingServices2005.RSConnection.IsSecureMethod(String methodname)

at Microsoft.SqlServer.ReportingServices2005.RSConnection.ValidateConnection()

at Microsoft.ReportingServices.UI.ReportingPage.EnsureHttpsLevel(HttpsLevel level)

at Microsoft.ReportingServices.UI.ReportingPage.ReportingPage_Init(Object sender, EventArgs args)

at System.EventHandler.Invoke(Object sender, EventArgs e)

at System.Web.UI.Control.OnInit(EventArgs e)

at System.Web.UI.Page.OnInit(EventArgs e)

at System.Web.UI.Control.InitRecursive(Control namingContainer)

at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
w3wp!ui!5!11/10/2006-08:32:40:: e ERROR: Exception in ShowErrorPage: System.Threading.ThreadAbortException: Thread was being aborted.
at System.Threading.Thread.AbortInternal()
at System.Threading.Thread.Abort(Object stateInfo)
at System.Web.HttpResponse.End()
at System.Web.HttpServerUtility.Transfer(String path, Boolean preserveForm)
at Microsoft.ReportingServices.UI.ReportingPage.ShowErrorPage(String errMsg) at at System.Threading.Thread.AbortInternal()
at System.Threading.Thread.Abort(Object stateInfo)
at System.Web.HttpResponse.End()
at System.Web.HttpServerUtility.Transfer(String path, Boolean preserveForm)
at Microsoft.ReportingServices.UI.ReportingPage.ShowErrorPage(String errMsg)

So that's it. Thanks for any help you can provide.

Nicolas

So? Anyone can assist me? Is this the right place to post an issue like this. I've searched a lot on the Web and I've yet to find a solution. The error message doesn't help me much either (As far as I can see, the report server is running since I can display the reports).|||

Here is something you can start with for investigation:

1. Check reportserver log file to see whether there is any error there.

2. Check IIS logging to make sure the request does get to report server (some times you need to iisreset to flush the most recent result).

3. You can use some tcp tracing tool to check the traffic between report manager and report server to check if anything wrong.

|||

Hi Yalei,

First, thanks for you help.

1. Check reportserver log file to see whether there is any error there:

Assuming you are refering to one of the "\Reporting Services\LogFiles\reportserver_*.log", i don't see anything wrong there. No "ERRORS", only "INFO". An entry such as the following:

"w3wp!library!5!11/14/2006-14:44:08:: i INFO: Cleaned 0 batch records, 0 policies, 0 sessions, 0 cache entries, 0 snapshots, 0 chunks, 0 running jobs, 0 persisted streams"

appears every 10 minutes. The log doesn't seem to react when I access http://<servername>/Reports$SQLSERVER_2005.

2. Check IIS logging to make sure the request does get to report server (some times you need to iisreset to flush the most recent result).

Below is a sample of my IIS Logging. I don't know if you can see something in it? Something that strikes me as strange is the time (the request is done circa 15:10 and the displayed hour is 20:17). The server time seems alright (i.e. circa 15:10) so I don't know where the logging gets its timestamp... Could this be the source of the problem?

Note: XXX.XXX.XXX.XXX is the server IP and YYY.YYY.YYY.YYY is the client IP.

#Date: 2006-11-14 20:17:04
#Fields: date time s-sitename s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status
2006-11-14 20:17:04 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005 - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 301 0 0
2006-11-14 20:17:21 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/Home.aspx - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 302 0 0
2006-11-14 20:17:26 W3SVC1 XXX.XXX.XXX.XXX POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - XXX.XXX.XXX.XXX - 302 0 0
2006-11-14 20:17:26 W3SVC1 XXX.XXX.XXX.XXX GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - XXX.XXX.XXX.XXX - 200 0 0
2006-11-14 20:17:28 W3SVC1 XXX.XXX.XXX.XXX POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - XXX.XXX.XXX.XXX - 302 0 0
2006-11-14 20:17:28 W3SVC1 XXX.XXX.XXX.XXX GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - XXX.XXX.XXX.XXX - 200 0 0
2006-11-14 20:17:29 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/Pages/Folder.aspx - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 500 0 0

2006-11-14 20:20:55 W3SVC1 XXX.XXX.XXX.XXX POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - XXX.XXX.XXX.XXX - 302 0 0
2006-11-14 20:20:55 W3SVC1 XXX.XXX.XXX.XXX GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - XXX.XXX.XXX.XXX - 200 0 0
2006-11-14 20:20:55 W3SVC1 XXX.XXX.XXX.XXX POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - XXX.XXX.XXX.XXX - 302 0 0
2006-11-14 20:20:55 W3SVC1 XXX.XXX.XXX.XXX GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - XXX.XXX.XXX.XXX - 200 0 0
2006-11-14 20:20:57 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/Pages/Folder.aspx - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 500 0 0
2006-11-14 20:20:57 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/js/ReportingServices.js - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 200 0 64
2006-11-14 20:20:57 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/styles/ReportingServices.css - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 200 0 64
2006-11-14 20:20:57 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/images/blank.gif - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 200 0 64
2006-11-14 20:20:57 W3SVC1 XXX.XXX.XXX.XXX GET /Reports$SQLSERVER_2005/images/48error.jpg - 80 - YYY.YYY.YYY.YYY Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 200 0 64

3. You can use some tcp tracing tool to check the traffic between report manager and report server to check if anything wrong.

Could this really cause problems? Like I've said, both report server and report manager are on the same machine. Also, when I use the "original" ".config" for Report Server and Report Manager, everything works OK. Do you still think it would be wortwhile to use TCP tracing tools? If so, can you recommend one (never used those...)?

Thanks again

|||

The following is suspicious. It happens again and again in the log. It is the redirection at Report Server. It should not happen when you perform login from report manager. This means from you cutomized UI login page at report manager, the forms auth cookie does not get passed in. You need to check that you called LogonUser soap API, retrieved the forms auth cookie and passed in the following request to report server.

2006-11-14 20:17:26 W3SVC1 XXX.XXX.XXX.XXX POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - XXX.XXX.XXX.XXX - 302 0 0
2006-11-14 20:17:26 W3SVC1 XXX.XXX.XXX.XXX GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - XXX.XXX.XXX.XXX - 200 0 0

|||

Thanks again for your support.

I do call LogonUser in my UILogon.aspx page (as well as my /MyWorkspace/Login.aspx page used for Report Server and my application). One thing I find weird is that when I access http://MSCAPP02/Reports$SQLSERVER_2005/, I am not redirected to the UILogon.aspx page. However, I can access the UILogon page directly and the page seems to work well by itself. Don't know why I keep getting redirected to Login.aspx. Here's the IIS Log when I log through the UILogon.aspx page:

2006-11-15 17:17:13 W3SVC1 172.17.70.73 GET /Reports$SQLSERVER_2005/Pages/UILogon.aspx - 80 - 142.101.228.177 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 200 0 0
2006-11-15 17:17:35 W3SVC1 172.17.70.73 POST /ReportServer$SQLSERVER_2005/ReportService.asmx - 80 - 172.17.70.73 - 200 0 0
2006-11-15 17:17:35 W3SVC1 172.17.70.73 POST /Reports$SQLSERVER_2005/Pages/UILogon.aspx - 80 - 142.101.228.177 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 302 0 0
2006-11-15 17:17:35 W3SVC1 172.17.70.73 POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - 172.17.70.73 - 302 0 0
2006-11-15 17:17:35 W3SVC1 172.17.70.73 GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - 172.17.70.73 - 200 0 0
2006-11-15 17:17:36 W3SVC1 172.17.70.73 POST /ReportServer$SQLSERVER_2005/ReportService2005.asmx - 80 - 172.17.70.73 - 302 0 0
2006-11-15 17:17:36 W3SVC1 172.17.70.73 GET /MyWorkspace/login.aspx ReturnUrl=%2fReportServer%24SQLSERVER_2005%2fReportService2005.asmx 80 - 172.17.70.73 - 200 0 0
2006-11-15 17:17:37 W3SVC1 172.17.70.73 GET /Reports$SQLSERVER_2005/Pages/Folder.aspx - 80 - 142.101.228.177 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.1;+SV1;+.NET+CLR+1.1.4322;+.NET+CLR+1.0.3705;+.NET+CLR+2.0.50727) 500 0 0

As I've said earlier, my code is mostly taken from an online tutorial. The code for the UILogon.aspx page is similar to that of my Login.aspx page. There does seem to be a good quantity of code to pass the auth cookie around (can't say I understand why all of this code does). In case you want to take a peek, here it is:

The code for the authentication in UILogon:

private void BtnLogon_Click(object sender, System.EventArgs e)
{
bool passwordVerified = false;
string sMsg = "";
string sUrl = "";

try
{
ReportServerProxy server = new ReportServerProxy();
server.Url = AuthenticationUtilities.GetWebServiceUrl();
server.LogonUser(TxtUser.Text, TxtPwd.Text, null);
passwordVerified = true;
}
catch (Exception ex)
{
return;
}
if (passwordVerified == true)
{
lblMessage.Text = "Logon successful: User is authenticated";
string redirectUrl = Request.QueryString["ReturnUrl"];
if (redirectUrl != null) HttpContext.Current.Response.Redirect(redirectUrl, false);
else HttpContext.Current.Response.Redirect("./Folder.aspx", false);
}
else
{
lblMessage.Text = "Invalid username or password";
}
}

... And the code for the ReportServerProxy which takes care of the cookie...

public class ReportServerProxy : ReportingService
{
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request;
request = (HttpWebRequest)HttpWebRequest.Create(uri);

// Create a cookie jar to hold the request cookie
CookieContainer cookieJar = new CookieContainer();
request.CookieContainer = cookieJar;
Cookie authCookie = AuthCookie;

// if the client already has an auth cookie
// place it in the request's cookie container
if (authCookie != null) request.CookieContainer.Add(authCookie);

request.Timeout = -1;
request.Headers.Add("Accept-Language", HttpContext.Current.Request.Headers["Accept-Language"]);
return request;
}

protected override WebResponse GetWebResponse(WebRequest request)
{
WebResponse response = base.GetWebResponse(request);
string cookieName = response.Headers["RSAuthenticationHeader"];

// If the response contains an auth header, store the cookie
if (cookieName != null)
{
Utilities.CustomAuthCookieName = cookieName;
HttpWebResponse webResponse = (HttpWebResponse)response;
Cookie authCookie = webResponse.Cookies[cookieName];

// If the auth cookie is null, throw an exception
if (authCookie == null)
{
throw new Exception("Authorization ticket not received by LogonUser");
}

// otherwise save it for this request
AuthCookie = authCookie;

// and send it to the client
Utilities.RelayCookieToClient(authCookie);
}
return response;
}

private Cookie AuthCookie
{
get
{
if (m_Authcookie == null)
m_Authcookie = Utilities.TranslateCookie(
HttpContext.Current.Request.Cookies[Utilities.CustomAuthCookieName]);
return m_Authcookie;
}
set
{
m_Authcookie = value;
}
}
private Cookie m_Authcookie = null;
}

... And the code for the Utilities class...

internal sealed class Utilities
{
internal static string CustomAuthCookieName
{
get
{
lock (m_cookieNamelockRoot)
{
return m_cookieName;
}
}
set
{
lock (m_cookieNamelockRoot)
{
m_cookieName = value;
}
}
}

private static string m_cookieName;
private static object m_cookieNamelockRoot = new object();

private static HttpCookie TranslateCookie(Cookie netCookie)
{
if (netCookie == null) return null;

HttpCookie webCookie = new HttpCookie(netCookie.Name, netCookie.Value);

// Add domain only if it is dotted - IE doesn't send back the cookie
// if we set the domain otherwise
if (netCookie.Domain.IndexOf('.') != -1)
webCookie.Domain = netCookie.Domain;

webCookie.Expires = netCookie.Expires;
webCookie.Path = netCookie.Path;
webCookie.Secure = netCookie.Secure;
return webCookie;
}

internal static Cookie TranslateCookie(HttpCookie webCookie)
{
if (webCookie == null) return null;
Cookie netCookie = new Cookie(webCookie.Name, webCookie.Value);

if (webCookie.Domain == null)
netCookie.Domain = HttpContext.Current.Request.ServerVariables["SERVER_NAME"];

netCookie.Expires = webCookie.Expires;
netCookie.Path = webCookie.Path;
netCookie.Secure = webCookie.Secure;
return netCookie;
}

internal static void RelayCookieToClient(Cookie cookie)
{
// add the cookie if not already in there
if (HttpContext.Current.Response.Cookies[cookie.Name] == null)
{
HttpContext.Current.Response.Cookies.Remove(cookie.Name);
}
HttpContext.Current.Response.SetCookie(TranslateCookie(cookie));
}
}

Sorry for the long post with lots of code. I'm not used to posting in forums so I'm not sure what is the best way to do this.

Like I said, this is basically the same code used by the Login.aspx page and it seems to work great there, so I guess it should be alright.

One thing I find kind of strange is the following in the Report Manger web.config:

<system.web>
[...]
<authentication mode="Windows" />
<identity impersonate="false" />
[...]
</system.web>

The step by step guide didn't ask to change it but should'nt this be mode="Forms"?

Thanks again, your support is really appreciated.

|||

Have you tried using hardcoding the url using \\localhost\ instead of machine IP in place of GetWebServiceURL().

string sUrl = "";
try
{
ReportServerProxy server = new ReportServerProxy();
server.Url = /ReportService2005.asmx" href="http://links.10026.com/?link=http://localhost//ReportService2005.asmx">http://localhost/<REPORTSERVER>/ReportService2005.asmx;
server.LogonUser(TxtUser.Text, TxtPwd.Text, null);
passwordVerified = true;
}
catch (Exception ex)
{
return;
}

|||

Hi Ross, thanks for your input.

Previously (a few days ago) GetWebServiceURL() was reading the url in a config file. But since I had problems with that, I modified GetWebServiceURL() to return a hardcoded string. Mine was http://<servername>/<reportserver>/ReportService.asmx instead of your http://localhost/<REPORTSERVER>/ReportService2005.asmx. So I decided to try yours but if anything, it is worse, i.e. when I authenticate from UILogon.aspx with my string, I get redirected to the error page:

"The report server is not responding. Verify that the report server is running and can be accessed from this computer"

When I use your string, I get the following exception:

System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: http://schemas.microsoft.com/sqlserver/2003/12/reporting/reportingservices/LogonUser. at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest() at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message) at System.Web.Services.Protocols.SoapServerProtocol.Initialize() at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

However, in both cases, if I try to access http://<servername>/Reports$SQLSERVER_2005/, I get the error page...

"The report server is not responding. Verify that the report server is running and can be accessed from this computer"

...instead of being redirected to the UILogon.aspx page (which I find puzzling).

Also, what's the difference between ReportService.asmx and ReportService2005.asmx? I sometimes wonder if this may be the source of my problems. Everywhere in my code, I was using ReportService.asmx.

Thanks

|||

Well it sounds like the web server is listening. However you may be passing a parameter in the HTTP request that does not match what the server is expecting.

I would double check to make sure the interface you are implementing is the one you are targeting.

using Microsoft.SqlServer.ReportingServices.ReportService2005;

....

public class ReportServerProxy : RS.ReportExecutionService

Where RS is a reference to /ReportServer/reportExecution2005.asmx" href="http://links.10026.com/?link=http:///ReportServer/reportExecution2005.asmx">http://<RSSERVER>/ReportServer/reportExecution2005.asmx

|||

Hi again Ross.

I've seen the following post: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=119960&SiteID=1 which answers the ReportService.asmx vs ReportService2005.asmx question. If I undrestand the answer correctly, I should be able to use ReportService.asmx, with a reduced feature set. Perhaps this reduced feature set means I can't use the 2005 version of Report Manager...

If you look at the code I posted, you'll see that I wasn't refering to ReportService2005 (in ReportService2005.asmx) but ReportService (in ReportService.asmx). Also, my proxy wasn't extending you RS.ReportExecutionService but the ReportingService class. So the exception is expected, in a way.

I'll try to rework my implementation using ReportService2005.asmx to see if I have any more luck and I'll let you know. I hope I don't have to change too many things as most of the code wasn't written by me, it was taken from a tutorial online.

|||

Hi Nicolas,

I'm a little bit past the issue you're having. I struggled with it a long......... time. As long as I run Report Server and Report Manager on the same machine things are fine with my custom security extension. The key in my case was to use the full machine.domain.com name everywhere. By everywhere I mean in both web.config files, the RSWebApplication.config file for ReportManager and the RSReportServer.config file on report server. Finally, in your browser always refrence the report manager url with the full machine.domain.com url never just 'machine' and certainly not with just localhost. I don't have the instance names as part of my VDirs but otherwise things are setup pretty similar to yours.

The problem I'm currently having is I'm trying to run ReportManager on a different box than ReportServer I get the exact same exception messages that you're seeing.

If anyone can verify that its possible to run ReportManager and ReportServer on different machines with a custom security extension I'd love to hear about it. I've also got a support call open with Microsoft and we're working the issue. I'll let the forum know how it turns out.....

cheers
Perry

|||

Hi Perry,

Thanks for your input.

In my case, I don't have a "machine.domain.com" (or if I do, i don't know what it is). This is a developpement server in an intranet. However, I do use the servername "everywhere" (i.e. in the config files and in the way I type my url in my browser). I think the key is just to be consistent in how you address it. Otherwise, I guess I could type in the IP address everywhere.

When you say your setup is similar to mine, do you mean my current setup (using "ReportService.asmx") or the one I was about to convert to (using "ReportService2005.asmx)?

As for running the services from different servers, have you seen the post below? You may find some clues in there...

http://groups.google.ca/group/microsoft.public.sqlserver.reportingsvcs/browse_frm/thread/991c9178ceab8f58/8f1a447aa60ad837?lnk=st&q=reporting+services+the+server+is+not+responding&rnum=3&hl=en#8f1a447aa60ad837

Thanks again

|||

Nicolas,

Did you ever work past your issue? I'm having an issue with a custom security extension that is a little different but related to cookies being passed from Report Manager to Reporting Services and I found your post. I'm curious if your problem was solved and if the solution would help me in any way.

Thanks,

Kyle

|||

Hi Kyle,

I haven't spent more time on the issue since my last post as other matters required my attention. However, I do plan to revisit the issue in the near future. If I do manage to make it work, I'll post here. If you have any solution hints on your side, these would be appreciated as well.

Cheers,

Nicolas

|||

Hey Nicolas,

I'm not 100% working but finally did find the major hang up I was having. Turns out it's a bug in how cookies are passed by controls in Report Manager. Namely when trying to view a report the custom authentication cookie is not passed to the Report Server.

Check this KB article just in case you're getting this error. The patch was free to get from support and it should be in the next service pack. If you get back to this and you're still stuck let me know. I know more about custom extensions then I ever planned on knowing at this point. :)

Happy Coding!

Kyle

www.kylefinley.net

Friday, March 9, 2012

RS Security Best Practices

Dear Anyone,

Does anyone know where I can find some papers regarding best practices on how to implement security in reporting services?

Thanks,

Joseph

Books Online should be a good start for overview. There is a whitepaper on how to develop a custom security extensions, but that might be beyone what you're looking for. If you have specific questions, please ask.

-Lukasz


This posting is provided "AS IS" with no warranties, and confers no rights.

Wednesday, March 7, 2012

RS Forms Authentication single sign-on problem

I am trying to implement the forms authentication (using the MSDN custom
security extension), to enable a single sign-on (SSO) between our web
application and RS. SSO works fine when both application and RS are on the
same machine. However, I haven't made SSO work when RS is on a different
machine. The RS login page always asks for credentials everytime I try to
generate a report through URL.
Based on some posts here, and MSDN suggestions, I have:
1. Modified the TranslateCookie methods and explicitly assigned our domain
name to netCookie.domain, and remove the conditional statements right after
it.
netCookie.domain = ".domain";
note: I am still testing on local domains (computername.domain). I
wonder if this is causing the problems. When deployed to production, this
will be something like appname.domain.com and reports.domain.com.
netCookie.domain = ".domain.com";
2. Modified both (our app and RS) web.config to have identical keys, based
on MSDN suggestion below.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconformsauthenticationacrossapplications.asp
3. Changed SessionState to "StateServer". Is this really needed?
Am I missing something else? I have included the IIS logs for more
information. RS is installed on a Win2K server and is not (yet) using SSL.
Need help badly. TIA.
#----
--
#Software: Microsoft Internet Information Services 5.0
#Version: 1.0
#Date: 2004-08-06 05:52:27
#Fields: date time c-ip cs-username s-ip s-port cs-method cs-uri-stem
cs-uri-query sc-status sc-win32-status cs(Cookie)
2004-08-06 05:52:27 192.168.15.14 - 192.168.15.156 80 GET /Default.htm - 200
0 -
2004-08-06 13:49:34 192.168.15.27 - 192.168.15.156 80 POST
/reportserver/ReportService.asmx - 200 0 -
2004-08-06 13:49:34 192.168.15.27 - 192.168.15.156 80 POST
/reportserver/ReportService.asmx - 200 0
sqlAuthCookie=09D2336BF9DC41B35067D85F16F19C522D5C1F393C96D4956B795C69DD69F2
CD7708825305DDA8C10E3489937AEE3D8FA1F8976C88A848B1775351841B8A3BE9
2004-08-06 13:49:34 192.168.15.27 - 192.168.15.156 80 POST
/reportserver/ReportService.asmx - 200 0
sqlAuthCookie=09D2336BF9DC41B35067D85F16F19C522D5C1F393C96D4956B795C69DD69F2
CD7708825305DDA8C10E3489937AEE3D8FA1F8976C88A848B1775351841B8A3BE9
#----
--Addendum:
I have viewed the IIS logs on both client machine (where web app is) and RS
server. It seems that the sqlAuthCookie was passed backed properly, from
the RS server, yet it still asks for credentials. See below.
IIS log from RS server:
2004-08-06 13:49:34 192.168.15.155 - 192.168.15.156 80 POST
/reportserver/ReportService.asmx - 200 0
sqlAuthCookie=09D2336BF9DC41B35067D85F16F19C522D5C1F393C96D4956B795C69DD69F2
CD7708825305DDA8C10E3489937AEE3D8FA1F8976C88A848B1775351841B8A3BE9
IIS log from client machine:
2004-08-06 13:49:34 192.168.15.155 POST /AAWeb/Login.aspx 302 0
ASP.NET_SessionId=3fhfoi55rbf4fiuvhaasi3rz
2004-08-06 13:49:34 192.168.15.155 GET /aaweb/default.aspx 200 0
ASP.NET_SessionId=3fhfoi55rbf4fiuvhaasi3rz;+sqlAuthCookie=09D2336BF9DC41B350
67D85F16F19C522D5C1F393C96D4956B795C69DD69F2CD7708825305DDA8C10E3489937AEE3D
8FA1F8976C88A848B1775351841B8A3BE9;+ASPXAUTH=D1226A0765C1A3CD447D1F329197886
8DB7478ED7CD849801633588BE5E6FF434B90ECF0344099C2E9341CD4F700AD5ADCDE0EC8F72
6B225E630F46A6947658C30AD53F0E628F6D1
"TechnoSpyke" <technospyke@.yahoo.com> wrote in message
news:OYRMCt8eEHA.704@.TK2MSFTNGP09.phx.gbl...
> I am trying to implement the forms authentication (using the MSDN custom
> security extension), to enable a single sign-on (SSO) between our web
> application and RS. SSO works fine when both application and RS are on
the
> same machine. However, I haven't made SSO work when RS is on a different
> machine. The RS login page always asks for credentials everytime I try to
> generate a report through URL.
> Based on some posts here, and MSDN suggestions, I have:
> 1. Modified the TranslateCookie methods and explicitly assigned our
domain
> name to netCookie.domain, and remove the conditional statements right
after
> it.
> netCookie.domain = ".domain";
> note: I am still testing on local domains (computername.domain). I
> wonder if this is causing the problems. When deployed to production, this
> will be something like appname.domain.com and reports.domain.com.
> netCookie.domain = ".domain.com";
> 2. Modified both (our app and RS) web.config to have identical keys,
based
> on MSDN suggestion below.
>
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconformsauthenticationacrossapplications.asp
> 3. Changed SessionState to "StateServer". Is this really needed?
> Am I missing something else? I have included the IIS logs for more
> information. RS is installed on a Win2K server and is not (yet) using
SSL.
> Need help badly. TIA.
>
#----
> --
> #Software: Microsoft Internet Information Services 5.0
> #Version: 1.0
> #Date: 2004-08-06 05:52:27
> #Fields: date time c-ip cs-username s-ip s-port cs-method cs-uri-stem
> cs-uri-query sc-status sc-win32-status cs(Cookie)
> 2004-08-06 05:52:27 192.168.15.14 - 192.168.15.156 80 GET /Default.htm -
200
> 0 -
> 2004-08-06 13:49:34 192.168.15.27 - 192.168.15.156 80 POST
> /reportserver/ReportService.asmx - 200 0 -
> 2004-08-06 13:49:34 192.168.15.27 - 192.168.15.156 80 POST
> /reportserver/ReportService.asmx - 200 0
>
sqlAuthCookie=09D2336BF9DC41B35067D85F16F19C522D5C1F393C96D4956B795C69DD69F2
> CD7708825305DDA8C10E3489937AEE3D8FA1F8976C88A848B1775351841B8A3BE9
> 2004-08-06 13:49:34 192.168.15.27 - 192.168.15.156 80 POST
> /reportserver/ReportService.asmx - 200 0
>
sqlAuthCookie=09D2336BF9DC41B35067D85F16F19C522D5C1F393C96D4956B795C69DD69F2
> CD7708825305DDA8C10E3489937AEE3D8FA1F8976C88A848B1775351841B8A3BE9
>
#----
> --
>