Dynamics 365 SDK 引发异常 "The Security Support Provider Interface (SSPI) negotiation failed"

Dynamics 365 SDK throws exception "The Security Support Provider Interface (SSPI) negotiation failed"

我正在通过 Microsoft.Xrm.Sdk + Microsoft.Pfe.Xrm.Core NuGet 包连接到 Active Directory 域中的 Dynamics 365 v9.0 本地组织以触发 SDK 请求。有时我会返回异常:The Security Support Provider Interface (SSPI) negotiation failed.

我的机器和 Dynamics 服务器位于不同的域中。 Fiddler 跟踪显示两台机器都可以在网络中访问。

PFE 库中抛出了异常,更具体地说是下面的 operation() 行。

Parallel.ForEach<TRequest, ParallelOrganizationOperationContext<TRequest, bool>>(requests,
    new ParallelOptions() { MaxDegreeOfParallelism = this.MaxDegreeOfParallelism },
    () => new ParallelOrganizationOperationContext<TRequest, bool>(),
    (request, loopState, index, context) =>
    {
        try
        {
            operation(request, threadLocalProxy.Value);
        }
        catch (FaultException<OrganizationServiceFault> fault)
        {
            //Track faults locally                                
            if (errorHandler != null)
            {
                context.Failures.Add(new ParallelOrganizationOperationFailure<TRequest>(request, fault));
            }
            else
            {
                throw;
            }
        }

        return context;
    },
    (context) =>
    {
        //Join faults together
        Array.ForEach(context.Failures.ToArray(), f => allFailures.Add(f));
    });

来源:https://github.com/seanmcne/XrmCoreLibrary/blob/8892a9e93c42d8c35aac2a212588d45359cfd1a2/v8/Client/ParallelServiceProxy.cs#L236

Sandrino Di Mattia 在 Early binding tips and tricks for Dynamics CRM 2011 文章中提供了解决方法:

If you’re working with a virtual machine that is part of an other domain you might get this error (cross domain call). To solve this you’ll need to change the way you pass the authentication arguments to CrmSvcUtil.exe Instead of calling CrmSvcUtil.exe using the following line:

    CrmSvcUtil.exe /url:"http:/srv/org/XRMServices/2011/Organization.svc" /out:Context.cs
    /username:"sandrino" /password:"pass" /domain:"somedomain" /serviceContextName:Context

Change it to the following:

    CrmSvcUtil.exe /url:"http:/srv/org/XRMServices/2011/Organization.svc" /out:Context.cs
    /username:"sandrino@somedomain" /password:"pass" /serviceContextName:Context

By removing the domain argument and appending the domain to the username (separated with the @ sign) you’ll solve the cross domain problem.