3

我在 Web 服务器 A 上有一个 MVC4 Web 应用程序,它使用 Web 服务器 B 上的 OrganizationServiceProxy 使用 Dynamics CRM Web 服务。MVC4 应用程序设置为启用了 ASP .NET 模拟和 Windows 身份验证。当我打电话给 WhoAmI 时,我收到一个错误:

'调用者未通过服务验证。'

现在,如果我将 MVC4 应用程序移动到具有与 Web 服务器 A 上相同的身份验证的 Web 服务器 B(与 CRM 相同),它会毫无例外地调用 WhoAmI。

这是用于连接到服务器的代码。

        string serviceURL = ConfigurationManager.AppSettings["CRMROOTURL"].ToString() + "XRMServices/2011/Organization.svc";

        this.CRMService = GetCRMService(serviceURL);

private OrganizationServiceProxy GetCRMService(string serviceURL)
{
        ClientCredentials credentials = new ClientCredentials();
        credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;

        OrganizationServiceProxy client
            = new OrganizationServiceProxy(new Uri(serviceURL), null, credentials, null);

        return client;
 }

这是 IIS 网站上的身份验证屏幕截图。

在此处输入图像描述

根据正确答案,我只想提供一些片段来帮助其他人。

string loggedUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

ClientCredentials credentials = new ClientCredentials();
credentials.Windows.ClientCredential = new NetworkCredential(username, password, domain);

OrganizationServiceProxy client
    = new OrganizationServiceProxy(new Uri(serviceURL), null, credentials, null);

client.ClientCredentials.Windows.ClientCredential = credentials.Windows.ClientCredential;

// -- Retrieve the user.
QueryExpression expression = new QueryExpression
{
    EntityName = "systemuser",
    ColumnSet = new ColumnSet("systemuserid")
};

expression.Criteria.AddCondition("domainname", ConditionOperator.Equal, loggedUser);

EntityCollection ec = client.RetrieveMultiple(expression);

if (ec.Entities.Count > 0)
{
    // -- Impersonate the logged in user.
    client.CallerId = ec.Entities[0].Id;
}

谢谢!

4

2 回答 2

3

除非您另有明确说明(并且没有任何代码来查看您如何创建 OrganizationServiceProxy),否则本地 OrganizationServiceProxies 将使用当前 AD 帐户(服务帐户,而不是用户的特定帐户)连接到 CRM。我猜您在服务器 A 上运行的应用程序池不是 CRM 用户,而服务器 B 上的用户是。如果是这样,请将服务器 A 的用户更改为与服务器 B 相同的用户,或者使服务器 A 的用户成为 CRM 中的用户。

编辑

您正在使用默认网络凭据连接到 CRM。这意味着无论您使用何种 IIS 身份验证,您都将作为应用程序池用户帐户连接到 CRM。只要应用程序池用户是 CRM 用户,此方法就可以工作,但可能不是您想要的。

您可以使用此方法手动设置网络凭据:

creds.Windows.ClientCredential = new System.Net.NetworkCredential("UserId", "Password", "DomainName");

然后获取 ASP.Net 用户的域名并使用模拟连接到 CRM 以确保正确应用该个人的所有安全性。

于 2013-09-06T19:11:57.847 回答
0

一些愚蠢的事情 - 小心你没有逃避你的用户名!

creds.Windows.ClientCredential = new NetworkCredential("domain\user", "PASSWORD");

请注意,\u 是一个转义序列 - 您需要输入“domain\user”。

于 2014-09-11T03:38:29.127 回答