SoapHttpClientProtocol.ReadResponse – The request failed with HTTP status 401: Unauthorized

asp.netauthenticationauthorizationreporting-serviceswindows-server-2003

I have an ASP.NET (v2.0) web application that uses a reference to a SQL Server Reporting Services 208 R2 instance (using the ReportService2010.asmx service endpoint). The web application is hosted on ServerA and the Reporting Services instance is hosted on ServerB. ServerA is running Windows Server 2003 (IIS6) and ServerB is running Windows Server 2008 R2.

The web application is configured to use Windows Authentication and impersonation is switched on. When I run the web application locally on ServerA (using a remote desktop connection) it works, but when I run from my desktop machine (Windows XP) I get the following error:

Server Error in '/MyWebApp' Application.

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.]
System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage
message, WebResponse response, Stream responseStream, Boolean
asyncCall) +431289
System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String
methodName, Object[] parameters) +204
ReportingServices.ReportingService2010.ListChildren(String ItemPath,
Boolean Recursive) +81 Default.LoadReports() +54
Default.Page_Load(Object sender, EventArgs e) +224
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object
o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender,
EventArgs e) +35 System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +50
System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
+627


Version Information: Microsoft .NET Framework Version:2.0.50727.3634;
ASP.NET Version:2.0.50727.3634

LoadReports method:

private void LoadReports()
{
    ReportingService2010 rService = new ReportingService2010();

    rService.Credentials = System.Net.CredentialCache.DefaultCredentials;
    CatalogItem[] catalogItems;
    catalogItems = rService.ListChildren(ReportPath, true);

    BuildTree(catalogItems);
}

The application event log on ServerA contains the following additional details:

Event Type: Warning
Event Source:   ASP.NET 2.0.50727.0
Event Category: Web Event 
Event ID:   1309
Date:       28/06/2012
Time:       11:25:16
User:       N/A
Computer:   ServerA
Description:
Event code: 3005 
Event message: An unhandled exception has occurred. 
Event time: 28/06/2012 11:25:16 
Event time (UTC): 28/06/2012 10:25:16 
Event ID: 11f6bec3e91045229f4e34a5d2de78e9 
Event sequence: 4 
Event occurrence: 1 
Event detail code: 0 

Application information: 
    Application domain: /LM/W3SVC/1/Root/MyWebApp-1-129853527126453497 
    Trust level: Full 
    Application Virtual Path: /MyWebApp 
    Application Path: c:\inetpub\wwwroot\MyWebApp\ 
    Machine name: ServerA 

Process information: 
    Process ID: 1180 
    Process name: w3wp.exe 
    Account name: NT AUTHORITY\NETWORK SERVICE 

Exception information: 
    Exception type: WebException 
    Exception message: The request failed with HTTP status 401: Unauthorized. 

Request information: 
    Request URL: http://ServerA/MyWebApp/Default.aspx 
    Request path: /MyWebApp/Default.aspx 
    User host address: 192.168.100.130 
    User: DOMAIN\mylogin 
    Is authenticated: True 
    Authentication Type: Negotiate 
    Thread account name: NT AUTHORITY\NETWORK SERVICE 

Thread information: 
    Thread ID: 1 
    Thread account name: NT AUTHORITY\NETWORK SERVICE 
    Is impersonating: False 
    Stack trace:    
   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 ReportingServices.ReportingService2010.ListChildren(String ItemPath, Boolean Recursive)
   at Default.LoadReports()
   at Default.Page_Load(Object sender, EventArgs e)
   at System.Web.Util.CalliHe.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Best Answer

Enable authentication delegation

Using the Active Directory Users and Computers Microsoft Management Console (Start > Run > "dsa.msc"), open the properties for the ServerA server entry. Under Delegation, select Trust this computer for delegation to any service (Kerberos only).

Configure SPNs

Use the following commands to register Service Principal Names (SPNs):

setspn -S http/ServerB ReportingServicesServiceAccount
setspn -S http/ServerB.domain.com ReportingServicesServiceAccount

Where ReportingServicesServiceAccount is the service account used to run the Reporting Services service on ServerB.