尝试使用CRM SOAP端点偶尔会抛出“用户ID无效”

时间:2013-09-10 17:08:21

标签: wcf authentication soap iis-7 dynamics-crm-2011

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

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

大多数时候,这一切都很有效。但是,一旦我们有了更多的测试人员,我们就会注意到CRM偶尔会停止为某些用户回复我们的服务,从而引发异常。如果该用户关闭浏览器并重新打开它,然后尝试完全相同的操作,则所有操作都会再次开始工作。我打开CRM服务器上的跟踪,发现当发生这种情况时,CRM正在记录“Crm异常:消息:用户ID无效。,ErrorCode:-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修复此问题。我们还没有找到一种方法来可靠地重现这一点,但它经常发生在用户身上。有人有什么想法吗?

1 个答案:

答案 0 :(得分:0)

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

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

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

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