【问题标题】:SSRS Reportviewer - 401 UnauthorizedSSRS Reportviewer - 401 未经授权
【发布时间】:2015-04-14 15:13:19
【问题描述】:

我们正在将 SQL Server 报告从 SQL Server 2008 (SP3) 机器转移到 SQL 2012 (SP1) 机器。报告在报告管理器中运行良好(即https://SQLRep2012/Reports)

但是,ASP.net 应用程序返回“请求失败,HTTP 状态 401:未授权。”

我知道用户拥有权限,因为我正在使用一个拥有所有网络/SQL 服务器权限的管理员帐户对其进行测试。

找到下面的代码...

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Security.Principal;
using System.Net;

public partial class Reports_ReportViewer : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.IsPostBack == false)
        {
            TimeReport GetReport1;
            GetReport1 = (TimeReport)Session["Report"];
            string FileName = GetReport1.GetReportFileName();

            //ReportViewer1.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Remote;
            ReportViewer1.ServerReport.ReportServerUrl = new Uri("https://SQLRep2012/ReportServer");
            ReportViewer1.ServerReport.ReportPath = "/TestReports/" + FileName;

            if (GetReport1.ParameterCount() != 0)
            {
                Microsoft.Reporting.WebForms.ReportParameter[] parameters1 = new Microsoft.Reporting.WebForms.ReportParameter[GetReport1.ParameterCount()];

                for (int i = 0; i < GetReport1.ParameterCount(); i++)
                {
                    parameters1[i] = new Microsoft.Reporting.WebForms.ReportParameter(GetReport1.ParameterName(i), GetReport1.ParameterValue(i));
                }

                //Create the creditial object and assign the username and password.
                ReportViewerCredentials rvc = new ReportViewerCredentials(ConfigurationManager.AppSettings["ReportUserID"],
                    ConfigurationManager.AppSettings["ReportUserPwd"],
                    ConfigurationManager.AppSettings["ReportUserDomain"]);

                //Make sure the credential object has the same report server url.
                rvc.ReportServerUrl = ReportViewer1.ServerReport.ReportServerUrl;

                //Save the credentials to the ReportViewer object.
                ReportViewer1.ServerReport.ReportServerCredentials = rvc;

                ReportViewer1.ServerReport.SetParameters(parameters1);
            }
        }       
    }
}
public class ReportViewerCredentials : Microsoft.Reporting.WebForms.IReportServerCredentials
{
    private string _username;
    private string _password;
    private string _domain;

    public Uri ReportServerUrl;

    public ReportViewerCredentials(string username, string password, string domain)
    {
        _username = username;
        _password = password;
        _domain = domain;
    }

    #region IReportServerCredentials Members

    public System.Security.Principal.WindowsIdentity ImpersonationUser
    {
        get
        {
            return null;
        }
    }
    public System.Net.ICredentials NetworkCredentials
    {
        get
        {
            System.Net.NetworkCredential nc = new NetworkCredential(_username, _password, _domain);
            CredentialCache cc = new CredentialCache();
            cc.Add(ReportServerUrl, "Negotiate", nc);
            return cc;
        }
    }
    public bool GetFormsCredentials
        (out Cookie authCookie,
        out string username,
        out string password,
        out string authority)
    {
        authCookie = null;
        authority = null;
        password = null;
        username = null;
        return false;
    }

    #endregion
}

【问题讨论】:

  • 谁是“用户”?使用浏览器的用户还是应用程序池用户?
  • 用户是有权运行相关报告的域用户。
  • 这不是我问的。通常(如果未进行不同配置)应用程序池用户是访问资源并需要适当权限的用户。
  • @gsharp 如果您在报表查看器上设置凭据,它不会使用应用程序池用户。
  • 同意@gsharp,我在 2016 年尝试此操作时还没有看到这种行为。即使之后,在报告查看器中手动设置凭据。我能够通过检查System.Security.Principal.WindowsIdentity.GetCurrent().Name 看到用户,然后在 IIS 管理器中将其更改为所需的用户。对于任何感兴趣的人,我有我的解决方案here。

标签: asp.net ssrs-2008 ssrs-2012


【解决方案1】:

在发布上述问题之前,我已经想出了答案。麻烦来自网络凭据。以前我有这个....

public System.Net.ICredentials NetworkCredentials
{
    get
    {
        System.Net.NetworkCredential nc = new NetworkCredential(_username, _password, _domain);
        CredentialCache cc = new CredentialCache();
        cc.Add(ReportServerUrl, "Negotiate", nc);
        return cc;
    }
}

但是,这对我在 SQL 2012 上不起作用。我不得不将其更改为这个。

public System.Net.ICredentials NetworkCredentials
{
    get
    {            
        return new NetworkCredential(_username, _password, _domain);
    }
}

【讨论】:

  • 我发布了这篇文章,希望它能帮助别人。我昨天会支付 20 美元来解决这个问题。 #stackoverflowROCKS
【解决方案2】:

在没有域参数的情况下创建 NetworkCredential 对我有用。

public System.Net.ICredentials NetworkCredentials
{
    get
    {            
        return new NetworkCredential(_username, _password);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 2018-05-19
    • 2020-06-11
    • 2017-02-22
    • 2018-10-08
    • 2018-01-05
    相关资源
    最近更新 更多