通过 Web 服务创建实体随机失败,错误为 0x80048405(访问被拒绝)

发布于 2024-10-11 22:13:22 字数 1875 浏览 2 评论 0原文

我们有一个公共 ASP.NET Web UI,用作底层 CRM4 实例的有限前端。通过 CRM4 SDK Web 服务实现通信:

var service = new Microsoft.Crm.SdkTypeProxy.CrmService();
service.Credentials = new System.Net.NetworkCredential("user", "pass", "domain");
service.Url = server + "/MSCRMServices/2007/CrmService.asmx";

var token = new CrmAuthenticationToken();
token.OrganizationName = organizationName;
service.CrmAuthenticationTokenValue = token;    
service.PreAuthenticate = true;

使用 xml 查询调用 fetch 总是成功,但实体创建有时会失败:

var entity = new DynamicEntity("some_entity");
var resultGuid = service.Create(entity);

iisreset 创建后总是失败。 IIS 日志显示对 CRMservice 的两个 POST 请求:

  1. 无用户、HTTP 401.5
  2. 域/用户、HTTP 500.0

返回的异常是:

[SoapException: Server was unable to process request.]
   System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) +1769861
   System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) +345
   Microsoft.Crm.SdkTypeProxy.CrmService.Create(BusinessEntity entity) +79

SoapException 详细信息:

<detail><error>
  <code>0x80048405</code>
  <description>Access is denied.</description>
  <type>Platform</type>
</error></detail>

当任何人使用 CRM 自己的 UI 手动创建 some_entity 时,事情会变得很奇怪。之后 Web 服务访问就可以正常工作了。

更多注意事项:

  1. CRM 自己的 UI 中的删除或更新不会修复 Web 服务访问
  2. CRM 应用程序池最多使用 1 个工作进程。
  3. 一段时间后,Web 服务再次中断为“访问被拒绝”(可能回收 wp)
  4. 错误不依赖于数据。
  5. 删除 PreAuthenticate 并没有改变任何东西。
  6. 事件日志中没有任何有用的内容。

谁能帮我摆脱那个奇怪的访问被拒绝错误?为什么触摸 CRM UI 会改变 Web 服务行为?

编辑: 尽管 Michael M 提供了该错误的解决方法,但我仍然不明白 CRM UI 为何/如何影响 CrmService 身份验证。

We have a public ASP.NET web UI which is used as limited frontend to underlying CRM4 instance. Communication is achieved through CRM4 SDK web service:

var service = new Microsoft.Crm.SdkTypeProxy.CrmService();
service.Credentials = new System.Net.NetworkCredential("user", "pass", "domain");
service.Url = server + "/MSCRMServices/2007/CrmService.asmx";

var token = new CrmAuthenticationToken();
token.OrganizationName = organizationName;
service.CrmAuthenticationTokenValue = token;    
service.PreAuthenticate = true;

Calling fetch with xml query always succeeds, but entity creation fails sometimes:

var entity = new DynamicEntity("some_entity");
var resultGuid = service.Create(entity);

After iisreset creation always fails. IIS log says two POST requests to CRMservice:

  1. no user, HTTP 401.5
  2. domain/user, HTTP 500.0

Exception returned is :

[SoapException: Server was unable to process request.]
   System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) +1769861
   System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) +345
   Microsoft.Crm.SdkTypeProxy.CrmService.Create(BusinessEntity entity) +79

Soapexception details:

<detail><error>
  <code>0x80048405</code>
  <description>Access is denied.</description>
  <type>Platform</type>
</error></detail>

Things get weird weird when anyone creates some_entity by hand using CRM's own UI. After that web service access works without problems.

More notes:

  1. deletion or update in CRM's own UI does NOT fix web service access
  2. CRM apppool uses max 1 worker process.
  3. After a while web service breaks again to the "access denied" (probably recycling wp)
  4. Errors do NOT depend on data.
  5. removing PreAuthenticate didn't change anything.
  6. Nothing useful in event log.

Could anyone help me get rid of that weird access denied error? Why touching CRM UI changes web service behavior?

EDIT:
Even though Michael M provided a workaround for the error, I still don't understand why/how does CRM UI affect CrmService authentication.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

早乙女 2024-10-18 22:13:22

您的令牌可能不正确。根据您的身份验证类型,您可能还需要更改令牌的 AuthenticationType。尝试以下方法来获取服务的实例。

private static CrmService GetService(string organization, string server, string domain,
                     string username, string password)
    {
        server = server.TrimEnd(new[] {'/'});

        // Initialize an instance of the CrmDiscoveryService Web service proxy.
        var disco
            = new CrmDiscoveryService
                {
                    Url = String.Format("{0}/MSCRMServices/2007/SPLA/CrmDiscoveryService.asmx", server)
                };

        //Retrieve a list of available organizations.
        var orgResponse =
            (RetrieveOrganizationsResponse) disco.Execute(
                new RetrieveOrganizationsRequest
                    {
                        UserId = domain + "\\" + username,
                        Password = password
                    });

        //Find the desired organization.
        foreach (var orgDetail in orgResponse.OrganizationDetails)
        {
            if (orgDetail.OrganizationName != organization)
                continue;

            //Retrieve the ticket.
            var ticketResponse =
                (RetrieveCrmTicketResponse) disco.Execute(
                    new RetrieveCrmTicketRequest
                        {
                            OrganizationName = organization,
                            UserId = domain + "\\" + username,
                            Password = password
                        });

            //Create the CrmService Web service proxy.
            var token = new CrmAuthenticationToken
                {
                    AuthenticationType = 2,
                    OrganizationName = organization,
                    CrmTicket = ticketResponse.CrmTicket
                };

            return new CrmService
                {
                    CrmAuthenticationTokenValue = token,
                    Url = orgDetail.CrmServiceUrl
                };
        }
        return null;
    }

It's possible that your token is not correct. Depending on your authentication type, you may also need to change the token's AuthenticationType. Try the following method to get an instance of the service.

private static CrmService GetService(string organization, string server, string domain,
                     string username, string password)
    {
        server = server.TrimEnd(new[] {'/'});

        // Initialize an instance of the CrmDiscoveryService Web service proxy.
        var disco
            = new CrmDiscoveryService
                {
                    Url = String.Format("{0}/MSCRMServices/2007/SPLA/CrmDiscoveryService.asmx", server)
                };

        //Retrieve a list of available organizations.
        var orgResponse =
            (RetrieveOrganizationsResponse) disco.Execute(
                new RetrieveOrganizationsRequest
                    {
                        UserId = domain + "\\" + username,
                        Password = password
                    });

        //Find the desired organization.
        foreach (var orgDetail in orgResponse.OrganizationDetails)
        {
            if (orgDetail.OrganizationName != organization)
                continue;

            //Retrieve the ticket.
            var ticketResponse =
                (RetrieveCrmTicketResponse) disco.Execute(
                    new RetrieveCrmTicketRequest
                        {
                            OrganizationName = organization,
                            UserId = domain + "\\" + username,
                            Password = password
                        });

            //Create the CrmService Web service proxy.
            var token = new CrmAuthenticationToken
                {
                    AuthenticationType = 2,
                    OrganizationName = organization,
                    CrmTicket = ticketResponse.CrmTicket
                };

            return new CrmService
                {
                    CrmAuthenticationTokenValue = token,
                    Url = orgDetail.CrmServiceUrl
                };
        }
        return null;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文