2

我们有一个带有汇总 13 的本地 CRM。一些表单需要填充来自多个来源并需要进行预处理的外部数据。为此,我们开发了一个自定义 WCF 服务,该服务在与 CRM 相同的服务器上运行,并作为 CRM 网站中的虚拟应用程序托管在 IIS 中(以避免跨域脚本问题),并将 REST 端点暴露给运行在客户关系管理表格。javascript 发出请求,服务收集和处理数据,然后用一些漂亮的简单 JSON 回复 javascript。

由于我们需要的一些数据来自 CRM 本身,我们认为我们会让服务也收集这些数据(使用 CRM 的 SOAP 端点),而不是直接从 javascript 向 CRM Web 服务发出请求。我们在 IIS 中设置了直通身份验证,因此我们的自定义应用程序在模拟登录到 CRM 的用户时向 CRM 发出请求。

大多数时候,这一切都很好。然而,一旦我们有更多的测试人员,我们开始注意到 CRM 偶尔会停止为某些用户回复我们的服务,从而引发异常。如果该用户关闭浏览器并重新打开它,然后尝试完全相同的操作,一切都会重新开始工作。我在 CRM 服务器上打开了跟踪,发现发生这种情况时,CRM 正在记录“Crm 异常:消息:用户 ID 无效。,错误代码:-2147214049”。下面的完整跟踪:

[2013-09-10 08:54:14.492] Process: w3wp |Organization:00000000-0000-0000-0000-000000000000 |Thread:   69 |Category: Exception |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: 4b901457-a545-4844-9ce8-b017d3833087 | CrmException..ctor  ilOffset = 0x36
at CrmException..ctor(Int32 errorCode, Object[] arguments)  ilOffset = 0x36
at SecurityLibrary.GetPrivilegedUserCallerAndBusinessGuidsFromThread(WindowsIdentity identity, IOrganizationContext context)  ilOffset = 0x6F
at SecurityLibrary.GetCallerAndBusinessGuidsFromThread(WindowsIdentity identity, Guid organizationId, LocatorServiceContext locatorServiceContext)  ilOffset = 0x56
at UserManagementFactory.ValidateSpecialUser(WindowsIdentity identity, Guid organizationId)  ilOffset = 0x1E
at WindowsIdentityAuthorizationManager.Authenticate(OperationContext operationContext)  ilOffset = 0x185
at WindowsIdentityAuthorizationManager.CheckAccessCore(OperationContext operationContext)  ilOffset = 0x22
at AuthorizationBehavior.Authorize(MessageRpc& rpc)  ilOffset = 0x28
at ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)  ilOffset = 0x293
at MessageRpc.Process(Boolean isOperationContextSet)  ilOffset = 0x62
at ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)  ilOffset = 0x1D7
at ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)  ilOffset = 0xF1
at ChannelHandler.AsyncMessagePump(IAsyncResult result)  ilOffset = 0x21
at AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)  ilOffset = 0x0
at AsyncResult.Complete(Boolean completedSynchronously)  ilOffset = 0xC2
at ReceiveItemAndVerifySecurityAsyncResult`2.InnerTryReceiveCompletedCallback(IAsyncResult result)  ilOffset = 0x55
at AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)  ilOffset = 0x0
at AsyncResult.Complete(Boolean completedSynchronously)  ilOffset = 0xC2
at AsyncQueueReader.Set(Item item)  ilOffset = 0x21
at InputQueue`1.Dispatch()  ilOffset = 0x121
at ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)  ilOffset = 0x22
at IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)  ilOffset = 0x5
at _IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)  ilOffset = 0x3C
>Crm Exception: Message: The user Id is invalid., ErrorCode: -2147214049
[2013-09-10 08:54:14.508] Process: w3wp |Organization:00000000-0000-0000-0000-000000000000 |Thread:   69 |Category: Platform.Sdk |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: 4b901457-a545-4844-9ce8-b017d3833087 | ServiceModelTraceRedirector.TraceData  ilOffset = 0x45
><TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error"><TraceIdentifier>http://msdn.microsoft.com/en-CA/library/System.ServiceModel.Diagnostics.TraceHandledException.aspx</TraceIdentifier><Description>Handling an exception.</Description><AppDomain>/LM/W3SVC/1/ROOT-6-130232384646037254</AppDomain><Exception><ExceptionType>Microsoft.Crm.CrmException, Microsoft.Crm.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</ExceptionType><Message>The user Id is invalid.</Message><StackTrace>   at Microsoft.Crm.BusinessEntities.SecurityLibrary.GetPrivilegedUserCallerAndBusinessGuidsFromThread(WindowsIdentity identity, IOrganizationContext context)
>   at Microsoft.Crm.BusinessEntities.SecurityLibrary.GetCallerAndBusinessGuidsFromThread(WindowsIdentity identity, Guid organizationId, LocatorServiceContext locatorServiceContext)
>   at Microsoft.Crm.Authentication.UserManagementFactory.ValidateSpecialUser(WindowsIdentity identity, Guid organizationId)
>   at Microsoft.Crm.Authentication.WindowsIdentityAuthorizationManager.Authenticate(OperationContext operationContext)
>   at Microsoft.Crm.Authentication.WindowsIdentityAuthorizationManager.CheckAccessCore(OperationContext operationContext)
>   at System.ServiceModel.Dispatcher.AuthorizationBehavior.Authorize(MessageRpc&amp;amp; rpc)
>   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp;amp; rpc)
>   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace><ExceptionString>Microsoft.Crm.CrmException: The user Id is invalid.
>   at Microsoft.Crm.BusinessEntities.SecurityLibrary.GetPrivilegedUserCallerAndBusinessGuidsFromThread(WindowsIdentity identity, IOrganizationContext context)
>   at Microsoft.Crm.BusinessEntities.SecurityLibrary.GetCallerAndBusinessGuidsFromThread(WindowsIdentity identity, Guid organizationId, LocatorServiceContext locatorServiceContext)
>   at Microsoft.Crm.Authentication.UserManagementFactory.ValidateSpecialUser(WindowsIdentity identity, Guid organizationId)
>   at Microsoft.Crm.Authentication.WindowsIdentityAuthorizationManager.Authenticate(OperationContext operationContext)
>   at Microsoft.Crm.Authentication.WindowsIdentityAuthorizationManager.CheckAccessCore(OperationContext operationContext)
>   at System.ServiceModel.Dispatcher.AuthorizationBehavior.Authorize(MessageRpc&amp;amp; rpc)
>   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp;amp; rpc)
>   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</ExceptionString></Exception></TraceRecord>

在我看来,某种安全令牌或某种缓存凭据会过期或以某种方式失效,并且我们的应用程序无法再向 CRM 进行身份验证。重新打开 IE 可以解决这个问题。我们还没有找到可靠地重现这种情况的方法,但它经常发生,足以引起用户的关注。有人有想法么?

4

1 回答 1

0

一种解决方法是取消通过身份验证。而是将您的 Web 服务更改为始终使用相同的 CRM 用户 ID 进行身份验证,并在成功通过身份验证后模拟用户。

设置新用户(例如“CRM Web 服务用户”)或选择现有用户帐户。确保该用户具有冒充其他用户的权限的安全角色,我认为正确的设置是在安全角色的业务管理下,称为“代表其他用户行事”。

设置此用户后,您需要调整 Web 服务,以便它们可以接受来自调用者的用户 ID。Web 服务将使用其配置的“CRM Web 服务用户”用户对 CRM 进行身份验证,但随后将模拟调用者传入的用户 ID(这反过来会为该用户应用正确的权限)。

这可能需要一些额外的工作,但它可以让您更好地控制身份验证以及如何处理故障。

于 2013-09-11T10:40:52.287 回答