You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 9 Blazor中Crystal Reports OpenDocument请求登录凭证问题

ASP.NET Core Blazor中使用OpenDocument调用Crystal Reports的登录令牌问题

我在ASP.NET Core 9 Blazor应用中需要运行Crystal Reports,尝试通过OpenDocument实现。目前能通过openDocument.jsp生成登录令牌,但打开生成的URL时,系统仍提示输入用户“crtoken”的密码。代码是从原本运行正常的.aspx应用转换过来的,已经接近解决但还没成功,求有相关经验的人指点。

我的代码:

private async void RunTheReport()
{
    if (report is not null)
    {
        string crystalURL = "http://webapp.companyname.com:6405/BOE/OpenDocument/opendoc/openDocument.jsp";
        string reportUserName = "crtoken";
        string password = "";
        string auth = "secEnterprise";
        string reportTokenURL = "http://webapp.companyname.com:6405/biprws/logon/long"; 
        string docURL = string.Empty;

        HttpClient httpClient = new HttpClient();

        var repStream = await httpClient.GetStreamAsync(reportTokenURL);
        StreamReader sr = new StreamReader(repStream);
        string output = sr.ReadToEnd();

        var newXml = new XmlDocument();
        newXml.LoadXml(output);

        XmlNodeList nodeList = newXml.GetElementsByTagName("attr");

        foreach (XmlNode node in nodeList)
        {
            if (node.Attributes["name"].Value == "userName")
            {
                node.InnerText = reportUserName;
            }

            if (node.Attributes["name"].Value == "password")
            {
                node.InnerText = password;
            }

            if (node.Attributes["name"].Value == "auth")
            {
                node.InnerText = auth;
            }
        }

        string logonToken = string.Empty;
        string encodedToken = string.Empty;
        byte[] reqBodyBytes = System.Text.Encoding.Default.GetBytes(newXml.OuterXml);

        var content = new StringContent(newXml.OuterXml, System.Text.Encoding.UTF8, "application/xml");

        var response = await httpClient.PostAsync(reportTokenURL, content);

        if (response.IsSuccessStatusCode)
        {
            string responseBody = await response.Content.ReadAsStringAsync();
            var responseXml = new XmlDocument();
            responseXml.LoadXml(responseBody);
            XmlNodeList newNodeList = responseXml.GetElementsByTagName("attr");

            if (newNodeList[0].Attributes["name"].Value == "logonToken")
            {
                logonToken = newNodeList[0].InnerText;
                encodedToken = logonToken;
            }
        }

        if (!string.IsNullOrEmpty(encodedToken))
        {
            docURL = $"{crystalURL}?sIDType=CUID@iDocID={report.Cuid}&X-SAP-LogonToken={encodedToken}&lsS@UserId={CurrentUser.UserId}";
        }

        if (docURL.Length > 0)
        {
            navigation.NavigateTo(docURL);
            //await jsRunTime.InvokeVoidAsync("open", docURL, "_blank");
        }
    }
}

可能的解决方向:

  • 修复URL参数格式:当前URL中的sIDType=CUID@iDocID={report.Cuid}存在格式错误,@应替换为&,正确写法是sIDType=CUID&iDocID={report.Cuid},否则OpenDocument无法正确解析文档标识参数。
  • 对令牌进行URL编码:获取到的logonToken可能包含特殊字符(如+、/、=),直接拼入URL会导致令牌失效。将encodedToken = logonToken改为encodedToken = Uri.EscapeDataString(logonToken)。
  • 修改异步方法签名:Blazor中应避免使用async void,将方法签名改为private async Task RunTheReport(),确保异步操作完成后再跳转页面。
  • 规范HttpClient使用:直接实例化HttpClient可能造成连接池耗尽,建议通过IHttpClientFactory注入HttpClient(在Program.cs中注册builder.Services.AddHttpClient(),然后在组件构造函数中注入)。
  • 验证令牌有效性:获取令牌后,可调用BIPRWS接口验证令牌是否有效,比如发送GET请求到http://webapp.companyname.com:6405/biprws/infostore,请求头带上X-SAP-LogonToken: {logonToken},如果返回成功则说明令牌有效,否则检查登录请求的参数是否正确。
  • 检查BOE服务器配置:确认BOE服务器是否允许空密码登录,若crtoken用户密码为空,需在BOE管理控制台中开启允许空密码登录的配置项。

内容的提问来源于stack exchange,提问作者user3498788

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 18:54:52