Средство просмотра отчетов SSRS + ASP.NET Исключение учетных данных 401
-
10-07-2019 - |
Вопрос
У меня есть отчет, сохраненный на сервере отчетов SQL2005, и я хочу вернуть обработанный PDF-файл этого отчета.Я понял это при работе с локальным файлом *.rdlc (и я написал об этом в блоге), но не тогда, когда *.rdl находится на сервере отчетов.Я получаю 401 Не Авторизован ошибка на линии...
reportViewer.ServerReport.SetParameters(reportDefinition.ReportParameters);
Вот метод, используемый для отображения отчета.
public byte[] Render(IReportDefinition reportDefinition)
{
var reportViewer = new ReportViewer();
byte[] renderedReport;
try
{
var credentials = new WindowsImpersonationCredentials();
reportViewer.ServerReport.ReportServerUrl = new Uri("http://myssrsbox", UrlKind.Absolute);
reportViewer.ServerReport.ReportServerCredentials = credentials;
reportViewer.ServerReport.ReportPath = reportDefinition.Path;
// Exception is thrown on the following line...
reportViewer.ServerReport.SetParameters(reportDefinition.ReportParameters);
string mimeType;
string encoding;
string filenameExtension;
string[] streams;
Warning[] warnings;
renderedReport = reportViewer.ServerReport.Render(reportDefinition.OutputType, reportDefinition.DeviceInfo, out mimeType, out encoding, out filenameExtension, out streams, out warnings);
}
catch (Exception ex)
{
// log the error...
throw;
}
finally
{
reportViewer.Dispose();
}
return renderedReport;
}
Другая вещь, которую вам не хватает, - это класс WindowsImpersonationCredentials .
public class WindowsImpersonationCredentials : IReportServerCredentials
{
public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority)
{
authCookie = null;
userName = password = authority = null;
return false;
}
public WindowsIdentity ImpersonationUser
{
get { return WindowsIdentity.GetCurrent(); }
}
public ICredentials NetworkCredentials
{
get { return null; }
}
public override string ToString()
{
return String.Format("WindowsIdentity: {0} ({1})", this.ImpersonationUser.Name, this.ImpersonationUser.User.Value);
}
}
Другие вещи, которые вам, возможно, потребуется знать...
- Это выполняется в интрасети, и олицетворение включено.
- Ведение журнала указывает на то, что пользователь олицетворения настроен правильно.
- Это действительно работает при запуске в Visual Studio (
http://localhost:devport
), и это действительно работает при запуске в моем окне разработки (http://localhost/myApplication
).IT не работает при запуске на наших тестовых или производственных серверах. - Я пробовал решения как с настройками system.net.defaultProxy в web.config, так и без них.Ни то, ни другое не сработало.
Что я делаю не так?Это настройка сервера?Это код?Это web.config?
Решение
Мы наконец-то разобрались с проблемой.Наши сетевые администраторы отключили двойное переключение, поэтому, хотя олицетворение корректно подключалось как domain\jmeyer
, приложение все еще пыталось подключиться к ящику SRS с domain\web01$
.Почему он так устроен?Потому что двойной переход - это огромная брешь в системе безопасности.(По крайней мере, так мне сказали.Похоже ли это на то, о чем вы бы читали дальше Ежедневный WTF?)
Наше решение состояло в том, чтобы создать универсальный domain\ssrs_report_services
пользователя и подключитесь к этому пользователю со следующими сетевыми учетными данными
public class CustomCredentials : IReportServerCredentials
{
public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority)
{
authCookie = null;
userName = password = authority = null;
return false;
}
public WindowsIdentity ImpersonationUser
{
get { return null; }
}
public ICredentials NetworkCredentials
{
get { return new NetworkCredential("ssrs_report_services", "password", "domain") ; }
}
}
Приведенное выше является классическим примером решения, которое вы можете найти по всему Интернету.
Другие советы
Разрешен "Двойной переход" - swith при аутентификации Kerberos ...(до тех пор, пока он работает должным образом!)