I have a C# application that I wrote to deploy reports to a SSRS instance. It has been working well. To improve security, I decided to change SSRS from using the NT AUTHORITY\NETWORK SERVICE account to using a dedicated domain account. I used the Reporting Services Configuration Manager to make the change. Now my app throws a MessageSecurityException:
The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate oYGEMIGBoAMKAQGiegR4YHYGCSqGSIb3EgECAgMAfmcwZaADAgEFoQMCAR6kERgPMjAxMjA3MjQxNzIyNTBapQUCAwUAuaYDAgEpqQ4bDFZFUlRFWC5MT0NBTKoqMCigAwIBA6EhMB8bBGhvc3QbF3Z0eC1kZXYtMDEudmVydGV4LmxvY2Fs'.
I call the following method:
public static ReportService.ReportingService2010SoapClient Connect(StreamWriter logFile, string reportingServicesUri)
{
//Connect with the user's Windows credentials
try
{
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
basicHttpBinding.SendTimeout = new TimeSpan(0, 10, 0);
EndpointAddress endpoint = new EndpointAddress(reportingServicesUri);
var rs = new ReportService.ReportingService2010SoapClient(basicHttpBinding, endpoint);
rs.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
rs.ChannelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
return rs;
}
catch (UriFormatException)
{
Common.WriteToLog(logFile, "Connect: " + reportingServicesUri + " does not point to a valid SSRS instance.", false);
}
return null;
}
I then call this method (which is where the exception is caught):
private static CatalogItem FindFirstItem(ReportingService2010SoapClient rs, StreamWriter logFile, String itemPath, String itemName)
{
CatalogItem[] items;
var itemsNames = new string[] { itemName };
string indentText = "";
Console.WriteLine(indentText + "Searching for " + itemPath + '/' + itemName + "...");
try
{
TrustedUserHeader userHeader = new TrustedUserHeader();
var properties = new Property[1];
properties[0] = new Property();
properties[0].Name = "Recursive";
properties[0].Value = "false";
var conditions = new SearchCondition[1];
conditions[0] = new SearchCondition();
conditions[0].Condition = ConditionEnum.Equals;
conditions[0].ConditionSpecified = true;
conditions[0].Name = "Name";
conditions[0].Values = itemsNames;
rs.FindItems(userHeader, "/" + itemPath, BooleanOperatorEnum.And, properties, conditions, out items);
if (items.Length == 0)
return null;
return items[0];
}
catch (FaultException e)
{
if (!e.Message.Contains("cannot be found"))
Common.WriteToLog(logFile, "FindFirstItem: " + e.Message, false);
}
catch (MessageSecurityException e)
{
throw;
}
return null;
}
I can still access the Data Sources for this SSRS instance using the Report Manager URL in a browser. My app still works on SSRS instances that use NT AUTHORITY\NETWORK SERVICE as the service account. How can I get this app working again with this SSRS instance?